按森林中的级别和节点 ID 标记节点

按森林中的级别和节点 ID 标记节点

我正在绘制家谱,我想用级别和 ID 标记每个节点,最好在每个级别重新开始。我希望得到以下输出,然后自动编号。这个问题提供了一种枚举节点的方法,但我还想添加级别(理想情况下,每个级别都重新开始编号)。任何帮助都将不胜感激。

\usepackage{forest}

\begin{document}
\begin{forest}
for tree={
  child anchor=south,
  parent anchor=north,
  grow'=north,
  draw,
}
[1-1 A 
    [2-1 B
        [3-1 C
        ]
        [3-2 D
            [4-1 E
            ]
            [4-2 F
            ]
        ]
    ]
]
\end{forest}

\end{document}

答案1

首先,请注意。原帖所引述的问题是关于 TikZ 树的,而这个问题是关于 Forest 树的。因此答案完全不同。

我们将通过几个示例慢慢构建解决方案。如果您对解释不感兴趣,请直接跳到最后一段代码。

Forest 提供了有关节点级别(选项level)和子节点编号(选项n)的信息,这些信息可以以各种方式插入到内容中;最简单的方法可能是使用宏。下面,我们使用(表示附加)\forestoption将此信息添加到内容的前面。请注意,我们必须用括号括住用于分隔标识符和其他内容的空格;如果我们不这样做,它将被键值解析机制“吃掉”。+contentcontent+pgfkeys

\documentclass{standalone}
\usepackage{forest}
\begin{document}

\begin{forest}
  for tree={
    child anchor=south,
    parent anchor=north,
    grow'=north,
    draw,
  },
  % We want to add to the content of the nodes (A, B, etc.), 
  % so we must "delay" the procedure to allow the content 
  % to be read in first.
  delay={
    for tree={
      +content={\forestoption{level}-\forestoption{n}{ }},
      % An alternative way of achieving the same, using the argument
      % processor (.process): 
      % * grab an "O"ption (level)
      % * grab another "O"ption (n), and 
      % * "w"rap the "two" options by macro "#1-#2{ }":
      % 
      % +content/.process={OOw2}{level}{n}{#1-#2{ }},
    },
  },
  [A
    [B
      [C]
      [D
        [E]
        [F]
      ]
    ]
  ]
\end{forest}

\end{document}

在此处输入图片描述

从结果来看,我们发现 (a) Forest 从 0 开始对层进行编号(但我们希望根位于 1 层),并且 (b) 根子节点编号为 0(我们希望为 1)。这两个问题都很容易解决。对于 (a),我们只需将 1 添加到层,使用 eTeX 的\numexpr:(\the\numexpr\forestoption{level}+1\relax可扩展)执行此操作。对于根,如果我们手动处理它是最简单的。

\documentclass{standalone}
\usepackage{forest}
\begin{document}

\begin{forest}
  for tree={
    child anchor=south,
    parent anchor=north,
    grow'=north,
    draw,
  },
  delay={
    % Take care of the root manually:
    +content={1-1\space},
    % We use "for descendants" instead of "for tree" now, 
    % so that we avoid visiting the root.
    for descendants={
      +content={\the\numexpr\forestoption{level}+1\relax-\forestoption{n}{ }},
    },
  },
  [A
    [B
      [C]
      [D
        [E]
        [F]
      ]
    ]
  ]
\end{forest}

\end{document}

在此处输入图片描述

这样就生成了 OP 所要求的树,但一般情况下它不起作用。如果节点也C有两个子节点(例如G和),它们将获得与节点和:和相同的标识符。显然,如果同一级别但属于不同父节点的节点要获得不同的 ID,我们就不能将子节点编号用作ID 的一部分。HEF4-1 G4-2 Hn

下面的想法是像往常一样遍历树(使用for tree,因为不需要对根进行特殊处理),并分别记住每个级别的最后访问节点的 ID(我们将使用一些低级 TeX 构造来执行此操作)。我们将这些“级别 ID”存储在名为 的控制序列中leveln<level number>。为了引用它们,我们定义一个辅助宏,\leveln将其扩展到当前节点的级别 ID 控制序列名称(leveln\forestoption{level}),然后使用\csname\leveln\endcsname来访问级别 ID 的值,或(etoolbox\csedef{\leveln}{...}来(重新)定义该值。

\documentclass{standalone}
\usepackage{forest}
\usepackage{etoolbox}
\begin{document}

% This produces the control sequence *name* of the counter for the current
% node's level; the idea is to use it in "\csname\leveln\endcsname" and such.
\def\leveln{leveln\forestoption{level}}

\begin{forest}
  for tree={
    child anchor=south,
    parent anchor=north,
    grow'=north,
    draw,
  },
  delay={
    for tree={
      % Step the level ID counter by one, or set it to 1 if it is not yet
      % defined.  The latter works because when "\csname\leveln\endcsname" is
      % not yet defined, it comes out meaning "\relax" (delimiting the end of
      %   the numeric expression), so we are evaluating "1+0"; and if it is
      % defined, say having value 42, then we are evaluating the numeric
      % expression 1+042, which is again what we want.
      TeX={\csedef{\leveln}{\the\numexpr1+0\csname\leveln\endcsname}},
      % Prepend to the content. We need to expand the prefix right away, 
      % because the value of "\csname\leveln\endcsname" is going to 
      % change way before the node is typeset.
      +content/.expanded={%
        % the level number, plus one
        \the\numexpr\forestoption{level}+1\relax
        % a dash and the level ID
        -\csname\leveln\endcsname
        % the space
        { }%
      },
    },
  },
  [A
    [B
      [C
        [E]
        [F]
      ]
      [D
        [G]
        [H]
      ]
    ]
  ]
\end{forest}

\end{document}

在此处输入图片描述

相关内容