5

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}
Helmut Grohne
  • 53
  • 1
  • 3
  • See also: [Using Macro Defined Lists in TikZ/PGFplots - TeX - LaTeX Stack Exchange](https://tex.stackexchange.com/questions/17833/using-macro-defined-lists-in-tikz-pgfplots) – user202729 Oct 15 '21 at 12:30

1 Answers1

0

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}).

Joel Berger
  • 20,180
  • 5
  • 49
  • 104
  • 1
    Uhm, so you hit precisely the same problem with your first approach? Your solution basically boils down to putting the `\node` in the macro, too. This should be possible without perltex, too. I didn't manage to get it compiled though. – Helmut Grohne Nov 08 '10 at 17:27
  • Yep, I agree that it seems that you should be able to put part of the TikZ command in a macro, but it doesn't seem to work. Yeah, in your case I am not sure that PerlTeX is going to help, until you would get into large numbers of nodes, in which case either PerlTeX or PgfFor will both get you the functionality you would want. – Joel Berger Nov 08 '10 at 17:30