лес - Измените цвет узлов после их создания, используя их автоматическое имя.

лес - Измените цвет узлов после их создания, используя их автоматическое имя.

Я попытался использовать решение, приведенное вэта почтадля воздействия на узлы дерева forest, но решение не работает с автоматическими именами, присвоенными forestузлам: см. MN(ot)WE ниже.

Есть ли способ это исправить? Если нет, то что делает что-то не так? Проблема с catcode?

\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}

решение1

Такие команды \aftercolorof{red}{!1}не работают, потому !1чтонетавтоматическое имя, присвоенное узлу лесом. Эти имена имеют форму node@N, с Nвозрастанием в порядке, в котором лес анализирует скобочное представление узла. Во втором дереве \aftercolorof{red}{node@3}цвета Aкрасные.

!1этоотносительное имя узла: инструкция о том, как достичь некоторого узла, начиная с другого узла. Например, в OP \aftercolorof{red}{!1}мы начинаем с корневого узла (весь код TikZ, следующий за спецификацией дерева, прикреплен к корневому узлу; и перед ) нет имени узла, !а затем переходим к его первому потомку, A.

Итак, чтобы код OP работал так, как задумано, нам нужно создать \aftercolorofи \changetxt принять относительные имена узлов. Это проще всего сделать, переопределив \labeltextof, как показано ниже, но будьте осторожны: код содержит внутреннюю команду леса \forest@nameandgo. Эта команда изменяет текущий узел леса, поэтому имя (или любой другой параметр) затем можно получить через \forest(e)option.

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

PS Forest вычисляет положение узлов второго уровня, используя исходный текст ( Bи C), поэтому «изменение» текста узла на \changetxtможет привести к получению неоптимального дерева.

Связанный контент