4

I'm wanting to sequentially transform an object in tikz by using, for example, a \foreach and to define a macro for the result after each step iteration. A simple example of what I'm trying to do is below. In my mind, the result should be an "X" at (2,0).

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}

\gdef\Stepi{\node at (0,0) {X};}
\newcount\Counter
\newcount\CounterOneLess

\Counter=1
\CounterOneLess=0
\foreach \i in {2,3}
{
    \global\advance\Counter by1
    \global\advance\CounterOneLess by1
    \expandafter\gdef\csname Step\romannumeral\Counter\endcsname
    {
        \protect\begin{scope}[shift={(1,0)}]
            \csname Step\romannumeral\CounterOneLess\endcsname
        \protect\end{scope}
    }
}

\Stepiii

\end{tikzpicture}

\end{document} 

However, when I try to run pdflatex, I get an error that says the TeX capacity (more specifically the allowable number of grouping levels) is exceeded. I'm guessing the error means I'm inadvertently causing an infinite loop and that it relates to my misunderstanding something about the expansion. Is there a way to get this concept working?

If it helps, the code works if I replace the

\csname Step\romannumeral\CounterOneLess\endcsname

inside the scope environment with a \Stepi. The result is an X at the expected location (that is, (1,0) in that case). Making this replacement defeats the purpose of course.

  • Welcome to TeX.SX! What is it you're actually trying to do? If your interest is in getting something to work, there's probably a much simpler way to do what you want using features of TikZ rather than all that TeX code. – Dai Bowen Nov 5 '16 at 16:40
  • It is probably because you are recursively embedding scopes and TikZ already uses a lot of group machinery within macros causing TeX to give up even after three recursions. I'm sure you are aware that you can simply shift the same picture around with a simple macro. – percusse Nov 5 '16 at 16:49
5
  • \xdef instead of \gdef inside the \foreach loop expands the definition text and the current counter values.

  • \noexpand instead of \protect prevents the expansion inside \xdef. \protect only works with LaTeX macros (\protected@edef, ...).

Fixed example:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}

\gdef\Stepi{\node at (0,0) {X};}
\newcount\Counter
\newcount\CounterOneLess

\Counter=1
\CounterOneLess=0
\foreach \i in {2,3}
{
    \global\advance\Counter by1
    \global\advance\CounterOneLess by1
    \expandafter\xdef\csname Step\romannumeral\Counter\endcsname
    {
        \noexpand\begin{scope}[shift={(1,0)}]
            \expandafter\noexpand\csname Step\romannumeral\CounterOneLess\endcsname
        \noexpand\end{scope}
    }
}
\Stepiii
\end{tikzpicture}
\end{document}

The business with the counters is not necessary here, because \foreach already offers all needed features:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}

\gdef\Stepi{\node at (0,0) {X};}

\foreach \i [evaluate=\i as \ioneless using int(\i-1)] in {2,3}
{
    \expandafter\xdef\csname Step\romannumeral\i\endcsname
    {
        \noexpand\begin{scope}[shift={(1,0)}]
            \expandafter\noexpand\csname Step\romannumeral\ioneless\endcsname
        \noexpand\end{scope}
    }
}

\Stepiii

\end{tikzpicture}
\end{document}
  • Perfect! Thank you so much. I appreciate the extra tip about the counters as well. – David Paige Nov 5 '16 at 17:08
2

With fewer \noexpand tokens:

\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\DefineStep}{m}
 {
  \paige_definestep:xx { \int_to_roman:n { #1 } } { \int_to_roman:n { #1 - 1 } }
 }
\cs_new_protected:Nn \paige_definestep:nn
 {
  \cs_gset:cpn { Step#1 }
   {
    \begin{scope}[shift={(1,0)}]
    \use:c { Step#2 }
    \end{scope}
   }
 }
\cs_generate_variant:Nn \paige_definestep:nn { xx }
\ExplSyntaxOff

\begin{document}

\begin{tikzpicture}
  \gdef\Stepi{\node at (0,0) {X};}
  \foreach \i in {2,3} { \DefineStep{\i} }
  \Stepi \Stepii \Stepiii
\end{tikzpicture}

\footnotesize
\texttt{\meaning\Stepi}

\texttt{\meaning\Stepii}

\texttt{\meaning\Stepiii}

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.