I tried to get around that by defining a value \def \col {5*(\m-1)+\n}
but that defines \col
as the string, not the value.
TeX is not a programming language.
You only define what the macro should expand to. If you want to do arithmetic on it, you could – powered by PGFMath – use
\pgfmathsetmacro\col{5*(\m-1)+\n}
then \col
will expand to an integer.
For \ifnum
you can now use \col
that way.
But you can also use \inteval
:
\ifnum\inteval{5*(\m-1)+\n}<…
which does the evaluation on the spot. (\inteval{…}
is basically the LaTeX equivalent of the TeX \numexpr…\relax
)
The LaTeX kernel defines much more programming macros that could help you tacke a problem programmatically but that's another topic, really, and some of them are already provided in the other answers.
In this answer, I want to provide some PGFKeys-powered solutions.
The first, the key set list of colors
defines colors tikzcol0
, tikzcol1
, … to be the given colors.
You then just have to choose the right one inside the loop.
Here, I'm using the evaluate
key that sets up the loop so that each evaluation is done at the start of each iteration. It would be similar to using \pgfmathsetmacro
or (in the case of int
) \pgfmathtruncatemacro
.
To retrieve the colors, the suffix is evaluated by PGFMath (the int
is necessary so we don't ask for the colors tikzcol0.0
, tikzcol1.0
, …).
I've also provided a .choose = {<list>}{<n>}
handler which finds – in a way – the nth entry in the list. However, each entry can occupy multiple neigbouring spots in the list. A list like 2 = foo, 5 = bar
means that the first two spots evaluate to foo
, while the next five spots return bar
. If you use an n that – in this case – is bigger than the available spots in the list, it will return no value.
As with everything in this answer, counting starts at 0. It makes the looping math easier and also applies to the .choose
handler.
If an entry of the list contains no equal sign than that entry occupies /utils/choose
(initally 3) spots.
This would actually allow you to just write
text/.choose={red, blue, green, orange, magenta}{\i}
% or
text/.choose={red, blue, green, orange, magenta}{\x+5*\y}
Code
\documentclass[tikz]{standalone}
\tikzset{
set list of colors/.style={
/utils/exec=\def\temp{-1},
/tikz/@set list of colors/.list={#1}},
@set list of colors/.code=%
\edef\temp{\inteval{\temp+1}}%
\colorlet{tikzcol\temp}{#1}}
\makeatletter
\tikzset{
/utils/choose/.initial=3,
/handlers/.choose/.code 2 args=%
\begingroup
\pgfmathtruncatemacro\pgfkeys@choose{#2}% make sure it's an integer
\let\pgfkeys@return\pgfkeysnovalue % fallback
\pgfqkeys{/handlers/.choose}{#1}%
\expandafter\endgroup\expandafter
\pgfkeys@exp@call\expandafter{\pgfkeys@return},
/handlers/.choose/.unknown/.code=%
\ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text
\let\pgfkeyscurrentvalue\pgfkeyscurrentname
\pgfkeysgetvalue{/utils/choose}\pgfkeyscurrentname
\fi
\ifnum\pgfkeyscurrentname>\pgfkeys@choose\relax
\let\pgfkeys@return\pgfkeyscurrentvalue
\pgfkeysdef{/handlers/.choose/.unknown}{}%
\fi
\edef\pgfkeys@choose{\the\numexpr\pgfkeys@choose-\pgfkeyscurrentname\relax}}
\makeatother
\begin{document}
\tikz[ % one loop
set list of colors={red, blue, green, orange, magenta}]
\foreach[evaluate={\x=mod(\i,5); \y=int(\i/5); \c=int(\i/3);}]
\i in {0, ..., 14}
\node[
text=tikzcol\c,
draw/.choose={1=red, 2=blue, green, 4=orange, 5=magenta}{\i}
] at (\x, -\y) {Foo};
\tikz[ % two loops
set list of colors={red, blue, green, orange, magenta}]
\foreach\y in {0, ..., 2}
\foreach[evaluate={\c=int((\x+5*\y)/3);}] \x in {0, ..., 4}
\node[
text=tikzcol\c,
draw/.choose={1=red, 2=blue, green, 4=orange, 5=magenta}{\x+5*\y}
] at (\x, -\y) {Foo};
\end{document}
Output