1

I have tried to use the solution given in this post to act on nodes of a forest tree but the solution does not work with automatic names given by forest to the nodes : see the MN(ot)WE below.

Is there a way to fix this ? If not what makes things going wrong ? A catcode problem ?

\documentclass{article}

\usepackage{tikz}
\usepackage{forest}

\makeatletter
\protected\def\tikz@fig@main#1{%
  \expandafter\gdef\csname labeltextof@\tikz@fig@name\endcsname{#1}%
  \iftikz@node@is@pic%
    \tikz@node@is@picfalse%
    \tikz@subpicture@handle{#1}%
  \else%
    \tikz@@fig@main#1\egroup%
  \fi}
\makeatother

\newcommand\labeltextof[1]{\csname labeltextof@#1\endcsname}
\newcommand{\aftercolorof}[2]{% #1 is the color, #2 us the node
  \path (#2.center) node[#1] {\labeltextof{#2}};
}

\newcommand{\changetxt}[2]{% #1 the node, #2 the text
  \path (#1.center) node[white, fill=white] {\labeltextof{#1}};
  \path (#1.center) node[black] {#2};
}


\begin{document}

\section{OK}

\begin{forest}
    [
        [$A$, name = nA
            [$B$, name = nB]
            [$C$, name = nC]
        ]
        [$D$, name = nD]
    ]
    \aftercolorof{red}{nA}
    \aftercolorof{blue}{nD}
    \changetxt{nB}{...}
    \changetxt{nC}{?}
\end{forest}


\section{KO}

\begin{forest}
    [
        [$A$
            [$B$]
            [$C$]
        ]
        [$D$]
    ]
    \aftercolorof{red}{!1}
    \aftercolorof{blue}{!2}
    \changetxt{!11}{...}
    \changetxt{!12}{?}
\end{forest}

\end{document}
0

1 Answer 1

4

Commands such as \aftercolorof{red}{!1} don't work because !1 is not the automatic name given to the node by forest. Those names are of form node@N, with N increasing in the order forest parses the bracket representation of the node. In the second tree, \aftercolorof{red}{node@3} colors A red.

!1 is a relative node name: an instruction of how to reach some node starting from another node. For example, in OP's \aftercolorof{red}{!1}, we start at the root node (all TikZ code following the tree specification is attached to the root node; and there is no node name in front of !) and then move to its first child, A.

So to make OP's code work as intended, we need to make \aftercolorof and \changetxt accept relative node names. This is easiest to do by redefining \labeltextof, as shown below, but be warned: the code contains forest's internal command \forest@nameandgo. This command changes forest's current node, so the name (or any other option) can then be accessed via \forest(e)option.

\makeatletter
\newcommand\labeltextof[1]{%
  \begingroup
  \forest@nameandgo{#1}%
  \edef\tempnodename{\foresteoption{name}}%
  \expandafter\endgroup
  \csname labeltextof@\tempnodename\endcsname
}
\makeatother

P.S. Forest computes the position of the second level nodes using the original text (B and C), so "changing" the node text by \changetxt might result in a sub-optimal tree.

1
  • Thanks a lot for explaining things. I love a lot the forest and its trees. ;-)
    – projetmbc
    Commented Aug 28, 2020 at 19:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .