1

I would like to write a macro that takes lists as some of its arguments and wonder how to best access the individual entries of these lists.

For example, I would like something of the sort

\newcommand\mycommand[4]{
\pgfmathsetmacro \n {{#1}}
\pgfmathsetmacro \k {{#2}}

\foreach \i in {\k,...,\n} {
 \draw (#3[\i],0) -- (#4[\i]) {};
}
}

which would take arguments such as

\mycommand{10}{3}{1,2,5}{6,9,10}

I would need to access both lists individually, so that working with a list of pairs seems not be an option. Basically my question is how to make the part #3[\i] work, which should return item number i in the list that is the third argument of the function.

  • 1
    The \getargsC{} macro of the readarray package (see http://tex.stackexchange.com/questions/2132/how-to-define-a-command-that-takes-more-than-9-arguments/99271#99271) allows a list of space-separated arguments that get placed into \argi, \argii, \argiii, etc. in roman numeral format. – Steven B. Segletes Apr 18 '16 at 16:41
  • Thanks for the hint, Steven! Is there also a way to access, say, number 25 by something like \arg[27] instead of the roman numbering? – Gandalf Lechner Apr 18 '16 at 17:36
  • 1
    \csname arg\romannumeral 27\endcsname, which you can implement as \def\myarg#1{\csname arg\romannumeral#1\endcsname} and invoke as \myarg{27}. – Steven B. Segletes Apr 18 '16 at 18:21
  • ah, nice! one more question: when I want to use that in a \foreach \i in ... loop, \myarg{\i} seems not to work? What would be the right way of accessing entry number \i? – Gandalf Lechner Apr 18 '16 at 19:42
  • I am not a \foreach expert, and you have not provided a complete length of code to compile. That said, I can do things like \foreach \y in {1,2,...,\the\numexpr\myarg{2}-1} successfully, followed by a \draw that uses \y. – Steven B. Segletes Apr 18 '16 at 20:08
  • I am trying to do \foreach \i in {1,...,10} { \node at (\i,0) {\myarg{\i}}; } which however fails for me – Gandalf Lechner Apr 18 '16 at 20:14

1 Answers1

1

This is a follow up to comments between the OP and myself.

Since full code was not provided and since I don't really know tikz at all, I grabbed another answer of mine at \foreach problem and show how to insert arguments from readarray package's \getargC macro into both \draw and \node macros, using the loop index as the argument.

Given an earlier call to \getargsC{15 43 35 21 1}, the particular stretch of code where that is used is

\foreach \y in {1,2,...,\the\numexpr\CylGrad-1}
    {\draw[semithick] (0,\y/\CylGrad)
        arc (270:260:1 and \CylRatio) ;
    \draw[semithick] (0,\y/\CylGrad)
        arc (270:280:1 and \CylRatio) (0.2,\y/\CylGrad)
        node[right,yslant=\CylRatio](\y){\footnotesize \myarg{\y}};% <--\myarg used here
    \node at (0,\y/\CylGrad){\myarg{\numexpr\y+1}};}; % <--\myarg used here
\fi

Here is the full MWE.

\documentclass[tikz]{standalone}
\usepackage{readarray}
\def\myarg#1{\csname arg\romannumeral#1\endcsname}

\pgfkeys{/tikz/.cd,
  CylCol/.store in=\CylCol,
  CylCol=gray,
  CylFillCol/.store in=\CylFillCol,
  CylFillCol=blue,
  CylFill/.store in=\CylFill,
  CylFill=0,
  CylRatio/.store in=\CylRatio,
  CylRatio=.08,  
  CylGrad/.store in=\CylGrad,
  CylGrad=5,
  CylSecondGrad/.store in=\CylSecondGrad,
  CylSecondGrad=0,
   }

\newcommand{\TikzCylindre}[1][]{%
    \begin{scope}[#1]
    % Grisé des surfaces du cylindre.
    \shade[left color=\CylCol!30, right color=\CylCol!5]%
         (-1,1)--(-1,0) arc (180:360:1 and \CylRatio) --(1,0) -- (1,1);
    \shade[left color=\CylCol!5, right color=\CylCol!30]%
        (0,1) ellipse (1 and \CylRatio);
    \draw[\CylCol!50] (1,0) arc (0:180:1 and \CylRatio)--(-1,0) ;

    % Remplissage du cylindre
    \shade[left color=\CylFillCol!40, right color=\CylFillCol!10]%
         (-1,\CylFill)--(-1,0) arc (180:360:1 and \CylRatio) --(1,0) -- (1,\CylFill);
    \fill[color=\CylFillCol!25] (0,\CylFill) ellipse (1 and \CylRatio);
    \draw[\CylFillCol!50!black!50] (1,0) arc (0:180:1 and \CylRatio)--(-1,0) ;
    \draw[\CylFillCol!50!black!50] (0,\CylFill) ellipse (1 and \CylRatio) ;

    % dessin des bords du cylindre
    \draw[semithick] (-1,1)--(-1,0) arc (180:360:1 and \CylRatio)--(1,0)--(1,1);
    \draw[semithick] (0,1) ellipse (1 and \CylRatio);   

        \begin{scope}[shift={(0,-\CylRatio)}]
        \ifnum\CylGrad>0
        \foreach \y in {1,2,...,\the\numexpr\CylGrad-1}
            {\draw[semithick] (0,\y/\CylGrad)
                arc (270:260:1 and \CylRatio) ;
            \draw[semithick] (0,\y/\CylGrad)
                arc (270:280:1 and \CylRatio) (0.2,\y/\CylGrad)
                node[right,yslant=\CylRatio](\y){\footnotesize \myarg{\y}};% <--\myarg used here
            \node at (0,\y/\CylGrad){\myarg{\numexpr\y+1}};}; % <--\myarg used here
        \fi

        \ifnum\CylSecondGrad>0
        \foreach \y in {1,2,...,\the\numexpr\CylSecondGrad}
        {\draw(0,\y/\CylSecondGrad) arc (270:265:1 and \CylRatio) ;
        \draw (0,\y/\CylSecondGrad) arc (270:275:1 and \CylRatio) ;
        };
        \fi
        \end{scope} ;

    \end{scope}
    }

\begin{document}

\getargsC{15 43 35 21 1}
\begin{tikzpicture}

    \TikzCylindre[x=1.5cm,y=4cm,CylFill=.8,CylSecondGrad=10] ;

\end{tikzpicture}

\end{document}

enter image description here