This answer may be more generic than specifically relating to TikZ/PGF.
(La)TeX is a macro-based language, so it does not work as expected compared to other languages when dealing with "arrays". For example, while \names[2]
should yield Laura
where
\def\names{Katie, Frank, Laura, Joe}
(indexing from 0), (La)TeX considers [2]
to have no connection to \names
. As such, you're more likely to obtain the output Katie, Frank, Laura, Joe[2]
- a concatenation of \names
(as it is defined) and [2]
.
In order to allow for indexing like one typically would using arrays, you would need some other functionality. Here's an example of a list parser that works like you would expect arrays do:
\documentclass{article}
\usepackage{xparse}% http://ctan.org/pkg/xparse
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcounter{listtotal}\newcounter{listcntr}%
\NewDocumentCommand{\names}{o}{%
\setcounter{listtotal}{0}\setcounter{listcntr}{-1}%
\renewcommand*{\do}[1]{\stepcounter{listtotal}}%
\expandafter\docsvlist\expandafter{\namesarray}%
\IfNoValueTF{#1}
{\namesarray}% \names
{% \names[<index>]
\renewcommand*{\do}[1]{\stepcounter{listcntr}\ifnum\value{listcntr}=#1\relax##1\fi}%
\expandafter\docsvlist\expandafter{\namesarray}}%
}
\begin{document}
\newcommand{\namesarray}{Katie, Frank, Laura, Joe}%
\verb|\names:|\ \names \par
\verb|\names[2]:|\ \names[2] \par
\verb|\names[0]:|\ \names[0] \par
\verb|\names[5]:|\ \names[5]
\end{document}
The idea here is to store the names in an array \namesarray
and then define a macro (or "function") that takes an optional argument. If no argument is supplied (i.e., you just use \names
), then you print the entire \namesarray
. If an argument is supplied (of the form \names[<index>]
), parse the list sequentially to find that item that matches <index>
and print it.
The list parser relies on etoolbox
's \docsvlist
and enumerator \do
.
The question seems a bit ill-defined, but one can indeed parse a general list in a nested way, and do different things based on the list length of each successive rank-1 list. Here
\loopy{1,2: 2,3,7: 2,4,4,5}
will place a 2
at location (1,2), since it was a 2-element list.
It will place a 3_7
at location (2,3), since 7
was the third element of the list starting with the coordinates (2,3).
Finally, it will place a 4_1
and 4_2
at (2,4) and (4,5) since the 4 element list began with 2,4
and concluded with 4,5
.
\documentclass{article}
\usepackage{listofitems,tikz}
\newcommand{\loopy}[1]{%
\setsepchar{:/,}%
\readlist\mylist{#1}%
\begin{tikzpicture}
\foreachitem\x\in\mylist[]{%
\ifnum\listlen\mylist[\xcnt]=2\relax
\node at (\mylist[\xcnt,1],\mylist[\xcnt,2]){$2$};
\else
\ifnum\listlen\mylist[\xcnt]=3\relax
\node at (\mylist[\xcnt,1],\mylist[\xcnt,2]){$3_{\mylist[\xcnt,3]}$};
\else
\ifnum\listlen\mylist[\xcnt]=4\relax
\node at (\mylist[\xcnt,1],\mylist[\xcnt,2]){$4_1$};
\node at (\mylist[\xcnt,3],\mylist[\xcnt,2]){$4_2$};
\fi
\fi
\fi
}
\end{tikzpicture}
}
\begin{document}
\loopy{1,2: 2,3,7: 2,4,4,5}
\end{document}
Best Answer
The TikZ
\foreach
macro is handy for situations like this:See section 56 ("Repeating Things: The Foreach Statement") in the TikZ/PGF v2.10 manual. The
count
option was introduced in TikZ v2.10, so you might need to update TikZ/PGF. The reason for usingcount
instead of LaTeX counters in that counters are defined globally, and I do not know how to easily get local counters (otherwise a second call to the macro will produce analready defined
error).