2

Is it possible to access an array and use one of its elements to specify the last iteration point in a TikZ \foreach?

I've tried with the code below but I keep getting a compilation error:

! Argument of \pgffor@@dotscharcheck has an extra }.
<inserted text>
                \par
l.49   }

And here's a minimal example:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{shapes}
\usetikzlibrary{arrows}
\usetikzlibrary{positioning}

\begin{document}

\begingroup
\newdimen\bitSize
\bitSize=2mm
\newdimen\bitSep
\bitSep=0.5mm
\newdimen\bitBigSep
\bitBigSep=3mm
\begin{tikzpicture}[%
    auto,
    every node/.style={%
      node distance=0pt,
    },
    bit/.style={%
      draw,
      rectangle,
      minimum size=\bitSize,
      inner sep=0pt,
      node distance=\bitSep,
    },
  ]

  \def\numBits{{4, 8, 4}}
  \foreach \i in {1, 2, 3} {%
    \pgfmathtruncatemacro\prevI{\i-1}
    \foreach \j in {1, ..., \numBits[\prevI]} {%
      \pgfmathtruncatemacro\prevJ{\j-1}

      % Draw bit
      \ifnum \j=1
        \ifnum \i=1
          \node [bit] (bit\i-\j) {};
        \else
          \node [bit, right=\bitBigSep of bit\prevI-\numBitsArray[\prevI-1]]
            (bit\i-\j) {};
        \fi
      \else
        \node [bit, right=of bit\i-\prevJ] (bit\i-\j) {};
      \fi
    }
  }
\end{tikzpicture}
\endgroup

\end{document}
gablin
  • 17,006
  • In the pgf manual (v.3.10) page 578, an example is given similar to what you have, implicitly, given. \foreach \x [remember=\x as \lastx (initially A)] in {B,...,H}{$\overrightarrow{\lastx\x}$, }. It remembers the previous iteration argument as \lastx. It would be much easier if you can provide an example showing what the goal is in your nested iteration. – percusse Sep 30 '11 at 11:49
  • Wait what? There is a PGF manual 3.10 now?! And I haven't even had time to read my printed 2.10 yet... Anyway, I don't understand how remember will help me here, but I actually managed to solve it with inspiration from this question: http://tex.stackexchange.com/questions/12091/tikz-foreach-loop-with-macro-defined-list – gablin Sep 30 '11 at 12:00
  • Oops, that should be 2.10. Sorry. And would you care posting your working solution here? – percusse Sep 30 '11 at 12:02
  • @percusse: Ah phew, got kind of scared there. ^^ Certainly, it is already posted. – gablin Sep 30 '11 at 12:03
  • 1
    my bad, I should have more coffee. One last thing, can you replace the ... with something that would compile e.g. \node at (\n,\j) {\n,\j}; such that one can execute the code and can obtain something, doesn't matter what. Sorry again :) – percusse Sep 30 '11 at 12:07
  • (Just to echo what percusse says) Although maybe now irrelevant for this question, it's a good idea in general to post something that people can just cut-and-paste into an editor. It makes it easier to start thinking about the question and so easier to help. – Andrew Stacey Sep 30 '11 at 12:15
  • Done. I think that was my original attempt (I'd already fixed it and had to remember how I approached it first). – gablin Sep 30 '11 at 13:15

1 Answers1

3

For anyone interested, here's how I solved it:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{shapes}
\usetikzlibrary{arrows}
\usetikzlibrary{positioning}

\begin{document}

\begingroup
\newdimen\bitSize
\bitSize=2mm
\newdimen\bitSep
\bitSep=0.5mm
\newdimen\bitBigSep
\bitBigSep=3mm
\begin{tikzpicture}[%
    auto,
    every node/.style={%
      node distance=0pt,
    },
    bit/.style={%
      draw,
      rectangle,
      minimum size=\bitSize,
      inner sep=0pt,
      node distance=\bitSep,
    },
  ]

  \def\numBitsList{4, 16, 4}
  \def\numBitsArray{{\numBitsList}}
  \foreach \n [count=\i] in \numBitsList {%
    \pgfmathtruncatemacro\prevI{\i-1}
    \pgfmathparse{\numBitsArray[\prevI]} \let\numBits\pgfmathresult
    \foreach \j in {1, ..., \numBits} {%
      \pgfmathtruncatemacro\prevJ{\j-1}

      % Draw bit
      \ifnum \j=1
        \ifnum \i=1
          \node [bit] (bit\i-\j) {};
        \else
          \pgfmathparse{\numBitsArray[\prevI-1]} \let\pprevJ\pgfmathresult
          \node [bit, right=\bitBigSep of bit\prevI-\pprevJ]
            (bit\i-\j) {};
        \fi
      \else
        \node [bit, right=of bit\i-\prevJ] (bit\i-\j) {};
      \fi
    }
  }
\end{tikzpicture}
\endgroup

\end{document}
gablin
  • 17,006