命名森林节点内的 tikz 节点以供参考

命名森林节点内的 tikz 节点以供参考

我正在制作一些带有解释和其他内容的语法/语义树。起初我创建了一个,node treetikz意味着我可以轻松指向所选节点以阐明这些节点。但是,我认为如果我将一个放在forest node tree单独的中tikz node,然后使用 furthertikz nodes指向 的各个部分,我可能会节省一些节点的输入forest tree。但这比我最初想象的要棘手。每次位置偏离时,我都需要求助于绝对定位(如果语法树是,我可以避免这种情况tikz node tree)。

我曾尝试将一个节点放在NP(\node (np) at (NP) {};),我曾尝试, tikz={\node[right=20pt of .west,inner sep=0pt] (NP) {x};forest nodeNP按照这个帖子,我尝试\tikzset{treen/.node=inner sep=2pt}for tree=treen按照这个帖子, 和\subnode{NP}{}按照这个帖子,但无济于事。那么,我是否错过了可以让其中一个(或其他东西)发挥作用的东西?或者我应该回到tikz树上?

梅威瑟:

% !TEX program = lualatex
\documentclass[12pt,b5paper,openany]{book}
\usepackage{fontspec}
\setlength\parskip{0pt}

\usepackage{polyglossia}
\setdefaultlanguage{english}

\usepackage[margin=2cm]{geometry}

\usepackage[skins,breakable]{tcolorbox}
\newtcolorbox{primary}[1][]{size=title,halign=center,valign=center,colback=black!10,#1}

\usepackage{tikz}
\tikzset{noddies/.style={draw=black,rectangle,fill=pink,align=left}}
\usetikzlibrary{positioning,tikzmark}

\usepackage{forest}

\begin{document}

The argument impacted by the verb gets fed in first:

\begin{figure}[ht!]
\begin{primary}
\begin{tikzpicture}[rounded corners]
    \node[noddies] (tree) at (0,) { \begin{forest}[S [NP,name=NP [argument [John]]][VP,name=VP [V [$\lambda x.cough(x)$ [coughed]]]]]\end{forest} };
    \node[noddies] (argument) at (-5,2.5) {argument};
    \node[noddies] (lambda) at (5,2.5) {verb function};

    \draw[-latex] (argument.east) -- (NP);
    \draw[-latex] (lambda.west) -- (tree);
\end{tikzpicture}
\end{primary}
    \label{fig:lambtree}
    \caption{1-place predicate \textit{cough} with tree}
\end{figure}

\end{document}

答案1

默认情况下,森林树会引入tikzpicture,因此将森林树放入 tikz 节点内会创建一个嵌套的tikzpicture。这不是很可取,例如这个帖子

不过,还是有办法解决这个问题的。首先,可以指示 Forest不是引入tikzpicture环境。这由 Forest 的键begin draw和控制end draw,默认为\begin{tikzpicture}\begin{tikzpicture}。将它们都设置为{},如下面的第一个和第二个解决方案所示,将树“直接”排版到中tikzpicture

解决问题的第二种方法(实际上是更常见的方法)是tikz在森林树规范的末尾(即树的最后一个右括号之后)简单地添加一些命令。这是下面第三个解决方案中使用的方法。

现在 OP 的示例引入了一个额外的问题:我们想在树周围放置一个填充的矩形,但是一旦树已经绘制好,这很难做到。在下面的第一个解决方案中很容易看到这个问题。如果我们删除opacity矩形上的键,树将不可见。也许有一个基于层的解决方案,但下面,我通过先绘制矩形然后绘制树来解决这个问题。Forest 在绘制树之前计算每个树节点的位置,因此如果我们在正确的时间(before drawing tree)使用此信息,我们可以在树之前绘制矩形。

fit node样式计算(使用 Forest 聚合函数.min.max)矩形的西北点和东南点,然后使用 TikZ 的排版矩形节点。 (这里面fit有一点黑魔法,可以将计算出的信息转发给。)排版的具体触发方式取决于 Forest 是否引入自己的排版(如上所述)。.processfittikzpicture

在第二个解决方案中,提供环境的是用户而不是森林tikzpicture。因此,我们已经在tikzpicture森林树规范正在处理的过程中,所以我们可以使用键TeX(在 的定义内fit node)插入矩形节点。

在第三个解决方案中,我们必须延迟矩形节点的排版,直到 Forest 打开自己的tikzpicture。但我们必须小心地在树节点之前绘制它,因此使用 Forest 的tikz键不会产生所需的结果。我们求助于修改 Forest 的样式;参见第三个解决方案中draw picture method的 的定义。fit node

第一个解决方案

% !TEX program = lualatex
\documentclass[12pt,b5paper,openany]{book}
\usepackage{fontspec}
\setlength\parskip{0pt}

\usepackage{polyglossia}
\setdefaultlanguage{english}

\usepackage[margin=2cm]{geometry}

\usepackage[skins,breakable]{tcolorbox}
\newtcolorbox{primary}[1][]{size=title,halign=center,valign=center,colback=black!10,#1}

\usepackage{tikz}
\tikzset{noddies/.style={draw=black,rectangle,fill=pink,align=left}}
\usetikzlibrary{positioning,tikzmark}

\usepackage{forest}

\begin{document}

The argument impacted by the verb gets fed in first:

\begin{figure}[ht!]
\begin{primary}
\begin{tikzpicture}[rounded corners]
  \begin{forest}
    begin draw/.code={},end draw/.code={},
    tikz={\node[noddies,fit to=tree,opacity=0.5](tree){};}
    [S [NP,name=NP [argument [John]]][VP,name=VP [V [$\lambda x.cough(x)$ [coughed]]]]]
  \end{forest}
  \node[noddies] (argument) at (-5,-0.5) {argument};
  \node[noddies] (lambda) at (5,-0.5) {verb function};
  
  \draw[-latex] (argument.east) -- (NP);
  \draw[-latex] (lambda.west) -- (tree);
\end{tikzpicture}
\end{primary}
    \label{fig:lambtree}
    \caption{1-place predicate \textit{cough} with tree}
\end{figure}

\end{document}

第一个解决方案

第二种解决方案

% !TEX program = lualatex
\documentclass[12pt,b5paper,openany]{book}
\usepackage{fontspec}
\setlength\parskip{0pt}

\usepackage{polyglossia}
\setdefaultlanguage{english}

\usepackage[margin=2cm]{geometry}

\usepackage[skins,breakable]{tcolorbox}
\newtcolorbox{primary}[1][]{size=title,halign=center,valign=center,colback=black!10,#1}

\usepackage{tikz}
\tikzset{noddies/.style={draw=black,rectangle,fill=pink,align=left}}
\usetikzlibrary{positioning,tikzmark}

\usepackage{forest}

\forestset{
  fit node/.style n args=3{
    tempdimxa/.min={x()+min_x()}{#1},
    tempdimxb/.max={x()+max_x()}{#1},
    tempdimya/.min={y()+min_y()}{#1},
    tempdimyb/.max={y()+max_y()}{#1},
    TeX/.process=R4w4
      {tempdimxa}{tempdimya}{tempdimxb}{tempdimyb}
      {\node[fit={(##1,##2)(##3,##4)},#2]{#3};},
  },
}

\begin{document}

The argument impacted by the verb gets fed in first:

\begin{figure}[ht!]
  \begin{primary}
    \begin{tikzpicture}[rounded corners]
      \begin{forest}
        begin draw/.code={},end draw/.code={},
        before drawing tree={fit node={tree}{noddies,name=tree}{}},
        [S [NP,name=NP [argument [John]]][VP,name=VP [V [$\lambda x.cough(x)$ [coughed]]]]]
      \end{forest}
      \node[noddies] (argument) at (-5,-0.5) {argument};
      \node[noddies] (lambda) at (5,-0.5) {verb function};
      
      \draw[-latex] (argument.east) -- (NP);
      \draw[-latex] (lambda.west) -- (tree);
    \end{tikzpicture}
  \end{primary}
  \label{fig:lambtree}
  \caption{1-place predicate \textit{cough} with tree}
\end{figure}

\end{document}

请注意,这棵树并不完全正确:John 和 lambda 节点之间没有分隔,就好像是 0 一样。我不确定这是怎么发生的;很可能,这与环境嵌入环境内部s sep这一事实有关。第三个解决方案不存在此缺陷。foresttikzpicture

第二种解决方案

第三种解决方案

% !TEX program = lualatex
\documentclass[12pt,b5paper,openany]{book}
\usepackage{fontspec}
\setlength\parskip{0pt}

\usepackage{polyglossia}
\setdefaultlanguage{english}

\usepackage[margin=2cm]{geometry}

\usepackage[skins,breakable]{tcolorbox}
\newtcolorbox{primary}[1][]{size=title,halign=center,valign=center,colback=black!10,#1}

\usepackage{tikz}
\tikzset{noddies/.style={draw=black,rectangle,fill=pink,align=left}}
\usetikzlibrary{positioning,tikzmark}

\usepackage{forest}

\forestset{
  fit node/.style n args=3{
    tempdimxa/.min={x()+min_x()}{#1},
    tempdimxb/.max={x()+max_x()}{#1},
    tempdimya/.min={y()+min_y()}{#1},
    tempdimyb/.max={y()+max_y()}{#1},
    draw tree method/.prefix code/.process=R4w4
      {tempdimxa}{tempdimya}{tempdimxb}{tempdimyb}
      {\node[fit={(##1,##2)(##3,##4)},#2]{#3};},
  },
}

\begin{document}

The argument impacted by the verb gets fed in first:

\begin{figure}[ht!]
  \begin{primary}
    \begin{forest}
      begin draw/.append code={[rounded corners]},
      before drawing tree={fit node={tree}{noddies,name=tree}{}},
      [S [NP,name=NP [argument [John]]][VP,name=VP [V [$\lambda x.cough(x)$ [coughed]]]]]
      % 
      \node[noddies] (argument) at (-5,-0.5) {argument};
      \node[noddies] (lambda) at (5,-0.5) {verb function};
      % 
      \draw[-latex] (argument.east) -- (NP);
      \draw[-latex] (lambda.west) -- (tree);
    \end{forest}
  \end{primary}
  \label{fig:lambtree}
  \caption{1-place predicate \textit{cough} with tree}
\end{figure}

\end{document}

第三种解决方案

相关内容