4

Why the following sample fails to compile in pdflatex when \ifeven is used?

It fails with many errors in line 34 (where the last closing brackets are). The errors are like: Undefined control sequence. }, Extra }, or forgoten \endgroup.}, Extra \else.}, Extra \fi }.

\documentclass[tikz]{standalone}

\newcommand{\stencilptreg}[4][]{\node[circle,fill,draw,inner sep=1.5pt,label={below:#4},#1] at (#2) (#3) {}}
\newcommand{\stencilptstg}[4][]{\node[circle,fill,white,draw=black,inner sep=1.5pt,label={below:#4},#1] at (#2) (#3) {}}

\begin{document}
        \begin{tikzpicture}[x=2cm,y=2cm]
            \pgfmathsetmacro\N{5};
            \pgfmathsetmacro\M{3};

            \pgfmathsetmacro\NN{(\N*2)};            % Number of points in staggered grid
            \pgfmathsetmacro\MM{(\M*2)};            % Number of points in staggered grid            

            \foreach \j [evaluate=\j as \q using {{int(\j/2)}}] in {0,1,...,\MM} {

                \ifodd\j
                    \draw [black!50,thin] (0,\j) node[red,left] {$n=\frac{\j}{2}$} -- (\N,\j);                  
                \else
                    \draw [black!50,thin] (0,\j) node[red,left] {$n=\q$} -- (\N,\j);
                \fi

                \foreach \i [evaluate=\i as \p using {(\i/2)}] in {0,1,...,\NN} 
                {
                    \ifodd\i
                        \ifodd\j
                            \stencilptstg{\p,\j}{x-\i-\j}{$\p$};
                        \fi
                    \else
                        %\ifeven\j
                            \pgfmathsetmacro{\p}{{int(\p)}};                
                            \stencilptreg{\p,\j}{x-\i-\j}{$\p$};
                        %\fi
                    \fi
                }
            }
        \end{tikzpicture}
\end{document}
Werner
  • 603,163
Lin
  • 1,191
  • Remark, the reason why the "undefined control sequence ifeven" is not the first error has something to do with how TeX balances conditionals while skipping through text, and it does not consider ifeven as a if-primitive (probably, I didn't trace very carefully) – user202729 Oct 10 '22 at 17:53

2 Answers2

6

You should look in the log file for the precise error message, rather than relying on the short tags shown by TeXStudio or other front-ends.

Running your file in batch mode, the first error message is

! Extra }, or forgotten \endgroup.
<argument> ...p ,\j }{x-\i -\j }{$\p $}; \fi \fi }

l.36 }

Not really clear, but a few lines down you see

! Extra \else.
\pgffor@collectargument ...pgffor@body {#1}}\else 
                                                  \expandafter \long \expand...
l.36 }

I'm ignoring this; it doesn't match any \if.

! Extra \fi.
\pgffor@collectargument ...r {\pgffor@body #1}\fi 
                                                  \pgffor@iterate 
l.36 }

We're getting closer! Let's go down some more:

! Undefined control sequence.
\pgffor@body ...i -\j }{$\p $}; \fi \else \ifeven 
                                                  \j \pgfmathsetmacro {\p }{...
l.36 }

The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

Hey! That's the problem!

TeX has no \ifeven and TikZ doesn't provide it. Actually, it is not possible to define an \ifeven command that works the same as \ifodd just reversing the test.

You can choose between

  \unless\ifodd\j\relax
    \pgfmathsetmacro{\p}{{int(\p)}};
    \stencilptreg{\p,\j}{x-\i-\j}{$\p$};
  \fi

or

  \ifodd\j\relax\else
    \pgfmathsetmacro{\p}{{int(\p)}};
    \stencilptreg{\p,\j}{x-\i-\j}{$\p$};
  \fi

I recommend \relax in order not to trigger premature expansions. Not a big deal here, but in other circumstances it could be crucial. However, it's not to be added for any numeric conditionals, particularly in contexts where full expansion is needed.

A safer protection might be

\ifodd\numexpr\j\relax\else

or

\unless\ifodd\numexpr\j\relax

but in this case it would be a waste.

egreg
  • 1,121,712
5

Because there is no \ifeven. However, it's equivalent to

\ifodd\j\else
  % <\ifeven> content
\fi

enter image description here

Werner
  • 603,163