5

How is it possible to use a declare function in the condition of \foreach? Here's my MWE:

\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[declare function={a = 0; b = 5;}]
  \foreach \x in {{a},...,{b}}{
    \draw (\x,0) -- (0,\x);
  }
\end{tikzpicture}
\end{document}

This gives me

Missing number, treated as zero.

(line 10, the closing bracket of the loop).

One can even use declared functions in the [options list] of tikzpicture in options coming behind declare function, but why not simply in \foreach?

Foo Bar
  • 13,247
  • I guess you can’t use it in foreach, because it doesn’t evaluate math at all, sin(2) doesn’t work either, does it? – Tobi Apr 26 '13 at 20:43
  • 1
    As already pointed out by comments and answers, you need to evaluate the values first. Although it is possible to say to evaluate an expression inside the loop using \foreach \x[evaluate=\x] in {…} the loop still uses the un-evaluated values, in this case the loop goes still from a to b and not from 0 to 5. {a, ..., e} would loop over a, b, c, d and e which could be some constants that get evaluated. You can't use it to loop over their values, unfortunately. – Qrrbrbirlbel Apr 26 '13 at 20:56

2 Answers2

5

You can evaluate the expression first:

\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[declare function={a=0;b = 5;}]
\pgfmathparse{{a}}\let\pgfmathresulta\pgfmathresult
\pgfmathparse{{b}}\let\pgfmathresultb\pgfmathresult
  \foreach \x in {\pgfmathresulta,...,\pgfmathresultb}{
    \draw (\x,0) -- (0,\x);
  }
\end{tikzpicture}

\end{document}
David Carlisle
  • 757,742
1

This small code adds two keys to the optional \foreach use:

  • use int and
  • use float

I let the example speak for themselves:

\begin{tikzpicture}[declare function={a = 0; b = 5;}]
  \foreach \x[use int=a to b] \draw (\x,0) -- (0,\x);
\end{tikzpicture}

\begin{tikzpicture}
    \foreach \x[use int=2 to 10 step 2] {
        \ifnum\x=\foreachEnd
            \tikzset{every path/.append style=thick}
        \fi
        \draw (\x/2,0) -- (0,\x/3);
    }
\end{tikzpicture}

Disclaimer: No warranties; probably breaks the very next moment.

Code

\documentclass[tikz]{standalone}
\usepackage{tikz}
\makeatletter
\newif\ifqrr@pgf@foreach@no@list
\pgfkeys{
    /pgf/foreach/.cd,
    @use/.code args={#1to#2}{%
        \qrr@pgf@foreach@no@listtrue
        \qrr@pgf@foreach@no@list@use\foreachStart{#1}%
        \pgfutil@in@{step}{#2}
        \ifpgfutil@in@
            \qrr@pgf@foreach@no@list@parse@step#2\pgffor@stop
        \else
            \qrr@pgf@foreach@no@list@parse@step#2step1\pgffor@stop
        \fi
        \edef\qrr@pgf@foreach@no@list@list{\foreachStart,\foreachSecond,...,\foreachEnd}},
    use int/.code={%
        \let\qrr@pgf@foreach@no@list@use\pgfmathtruncatemacro
        \pgfkeysalso{/pgf/foreach/@use={#1}}%
    },
    use float/.code={%
        \let\qrr@pgf@foreach@no@list@use\pgfmathsetmacro
        \pgfkeysalso{/pgf/foreach/@use={#1}}%
    }
}
\def\qrr@pgf@foreach@no@list@parse@step#1step#2\pgffor@stop{%
    \qrr@pgf@foreach@no@list@use\foreachEnd{#1}%
    \qrr@pgf@foreach@no@list@use\foreachSecond{\foreachStart+#2}%
}
\def\pgffor@vars{% manually extended, better etoolbox
    \pgfutil@ifnextchar i{\pgffor@@vars@end}{%
        \pgfutil@ifnextchar[{\pgffor@@vars@opt}{%]
            \pgfutil@ifnextchar/{\pgffor@@vars@slash@gobble}{%
                \ifqrr@pgf@foreach@no@list\expandafter\pgfutil@firstoftwo\else
                    \expandafter\pgfutil@secondoftwo\fi
                {\qrr@pgf@foreach@no@listfalse\pgffor@macro@list\qrr@pgf@foreach@no@list@list}
                {\pgffor@@vars}}}}}%
\makeatother
\begin{document}
\begin{tikzpicture}[declare function={a = 0; b = 5;}]
  \foreach \x[use int=a to b] \draw (\x,0) -- (0,\x);
\end{tikzpicture}

\begin{tikzpicture}
    \foreach \x[use int=2 to 10 step 2] {
        \ifnum\x=\foreachEnd
            \tikzset{every path/.append style=thick}
        \fi
        \draw (\x/2,0) -- (0,\x/3);
    }
\end{tikzpicture}
\end{document}

Output

enter image description here

enter image description here

Qrrbrbirlbel
  • 119,821