在 tikzpictures 中使用宏?

发布于 2024-09-30 15:50:41 字数 586 浏览 3 评论 0原文

我尝试使用以下 newcommand 压缩 tikzpicture

\newcommand{\tchild}[3]{ child { node{#2} #3 edge from parent node[above]{#1} } }
%intended usage: \tchild{edge label}{vertex label}{child nodes}

如果我将其应用于以下示例,我会得到一个工作文档。但是,在下面给出的示例中,pdflatex 给出了Package pgf Error: No shape named isknown.(请注意“named”和“is”之间的双空格)。如果我手动展开第二个tchild,我也会得到一个工作文档。有什么想法这里出了什么问题吗?

\begin{tikzpicture}
    \node{0} [grow'=right]
        \tchild{0}{1}{}
        \tchild{1}{0}{};
\end{tikzpicture}

I tried to compress a tikzpicture using the following newcommand:

\newcommand{\tchild}[3]{ child { node{#2} #3 edge from parent node[above]{#1} } }
%intended usage: \tchild{edge label}{vertex label}{child nodes}

If I apply it to the following example, I get a working document. However With the example given below pdflatex gives a Package pgf Error: No shape named is known. (notice the double space between "named" and "is"). If I manually expand the second tchild I get a working document, too. Any ideas what goes wrong here?

\begin{tikzpicture}
    \node{0} [grow'=right]
        \tchild{0}{1}{}
        \tchild{1}{0}{};
\end{tikzpicture}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白况 2024-10-07 15:50:41

编辑:有关 PerlTeX 与 TikZ 的一些非常酷(且有效)的示例,请参阅此 拖船文章

我相信这是因为 TikZ 图片的语法通常比 LaTeX 更加自由。我可以在 pgfmanual 中看到,当将 tikz 命令放入宏中时,宏包含 tikzpicture 环境(例如,参见 pgfmanual.pdf 的第 223 页,即库部分 (IV) 的第一页)。

我知道我会打破记录,但为了定义复杂的宏,我建议如果可能的话使用 PerlTeX。这允许定义更复杂的宏,并且还可以避免一些扩展后的混乱。

编辑:下面的(参见旧的)不起作用,因为 PerlTeX 宏必须返回完整的 TikZ 命令,为此我模拟了这个版本。新的命令树采用三个参数:根名称、根节点参数,然后是您最初拥有的三个命令,但设置不同。每个子命令由冒号 (:) 分隔,三个原始命令由逗号 (,) 分隔。也许更容易看到代码本身。同样,编译命令与 OLD 中的相同。

\documentclass{article}
\usepackage{perltex}

\usepackage{tikz}

\perlnewcommand{\tree}[3]{ 
  my ($root,$root_opts,$children) = @_;
  my @children = split(/\:/, $children);

  my $return = '';

  $return .= sprintf( "\\node{%s} \[%s\]\n", $root,$root_opts);

  foreach my $child (@children) {
    my ($edge, $vertex, $child_nodes) = split(/,/, $child);
    $child_nodes ||= '';
    $return .= sprintf("child { node{%s} %s edge from parent node[above]{%s} }\n",$vertex,$child_nodes,$edge);
  }
  $return .= "\;\n"; 
  return $return;
}

\begin{document}
\begin{tikzpicture}
%    \node{0} [grow'=right]
%      child { node{1}  edge from parent node[above]{0} }
%     child { node{0}  edge from parent node[above]{1} };
  \tree{0}{grow'=right}{0,1:1,0}
\end{tikzpicture}
\end{document}

--- BEGIN OLD ---

我尝试将一些东西组合在一起,但它无法编译(可能是因为我从未使用 TikZ 来制作树)。也就是说,也许问题在于没有让 PerlTeX 执行足够的 TikZ 命令。将 perl 哈希转换为 TikZ 树可能是一个非常酷的项目。不管怎样,它就在这里。请注意,您使用 perltex --latex=pdflatex text.tex 进行编译:

\documentclass{article}
\usepackage{perltex}

\usepackage{tikz}

\perlnewcommand{\tchild}[3]{ 

  my ($edge, $vertex, $child) = @_;

  $child ||= '';

  my $return = 'child { node{' . $vertex . '} ' . $child . ' edge from parent node[above]{' . $edge . '} }';

  return $return;
}

\begin{document}
\begin{tikzpicture}
    \node{0} [grow'=right]
        \tchild{0}{1}{}
        \tchild{1}{0}{}
    ;
\end{tikzpicture}
\end{document}

--- END OLD ---

话虽如此,也许您的问题是如何处理可选的#3,也许如果您确实将其设置为可选而不是定义和空它会更好地工作(即 \tchild[]{0}{1})。

Edit: For some really cool (and working) examples of PerlTeX with TikZ see this TUGboat article!

I believe this is due to the fact that the syntax of a TikZ picture is much more freeform than LaTeX generally. I can see that in the pgfmanual when putting tikz commands into a macro, the macro contains the tikzpicture environment (see for example page 223 of pgfmanual.pdf, that is the first page of the Libraries section (IV)).

I know that I get to be a broken record but for defining complicated macros, I recommend using PerlTeX if at all possible. This allows for far more complicated macros to be defined and it also allows some of the expandafter mess to be avoided.

Edit: The below (see OLD) didn't work because a full TikZ command must be returned by the PerlTeX macro, to this end I mocked up this version. The new command tree takes three arguments the root name, the root node arguements and then the three commands that you originally had, however setup differently. Each child is separated by a colon (:) and the three original commands are separated by commas (,). Perhaps its easier to see the code itself. Again the compiling command is the same as in OLD.

\documentclass{article}
\usepackage{perltex}

\usepackage{tikz}

\perlnewcommand{\tree}[3]{ 
  my ($root,$root_opts,$children) = @_;
  my @children = split(/\:/, $children);

  my $return = '';

  $return .= sprintf( "\\node{%s} \[%s\]\n", $root,$root_opts);

  foreach my $child (@children) {
    my ($edge, $vertex, $child_nodes) = split(/,/, $child);
    $child_nodes ||= '';
    $return .= sprintf("child { node{%s} %s edge from parent node[above]{%s} }\n",$vertex,$child_nodes,$edge);
  }
  $return .= "\;\n"; 
  return $return;
}

\begin{document}
\begin{tikzpicture}
%    \node{0} [grow'=right]
%      child { node{1}  edge from parent node[above]{0} }
%     child { node{0}  edge from parent node[above]{1} };
  \tree{0}{grow'=right}{0,1:1,0}
\end{tikzpicture}
\end{document}

--- BEGIN OLD ---

I have tried to hack something together, although, it isn't compiling (probably due to the fact that I have never used TikZ to make trees). That said, perhaps the problem is not letting PerlTeX do enough of the TikZ command. Converting a perl hash to a TikZ tree might be a very cool project. Anyway here it is. Note that you compile it with perltex --latex=pdflatex text.tex:

\documentclass{article}
\usepackage{perltex}

\usepackage{tikz}

\perlnewcommand{\tchild}[3]{ 

  my ($edge, $vertex, $child) = @_;

  $child ||= '';

  my $return = 'child { node{' . $vertex . '} ' . $child . ' edge from parent node[above]{' . $edge . '} }';

  return $return;
}

\begin{document}
\begin{tikzpicture}
    \node{0} [grow'=right]
        \tchild{0}{1}{}
        \tchild{1}{0}{}
    ;
\end{tikzpicture}
\end{document}

--- END OLD ---

All that said, perhaps your problem is how you are treating the optional #3, perhaps if you really made that optional rather than defined and empty it would work better (i.e., \tchild[]{0}{1}).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文