5

The following works as expected:

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
    \makeatletter
    \node (01) at (0, 0) {};
    \draw (0, 0) -- (0, 01);
    \makeatother
\end{tikzpicture}
\end{document}

But when I replace one of the 01s with \@ifnextchar1001, which should be equivalent according to my understanding, it breaks:

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
    \makeatletter
    \node (\@ifnextchar1001) at (0, 0) {};
    \makeatother
\end{tikzpicture}
\end{document}

gives

! Argument of \XC@definec@lor has an extra }.
<inserted text> 
                \par 
l.6   \node (\@ifnextchar1001)
                              at (0, 0) {};

and

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
    \makeatletter
    \draw (0, 0) -- (0, \@ifnextchar1001);
    \makeatother
\end{tikzpicture}
\end{document}

yields

! Argument of \XC@definec@lor has an extra }.
<inserted text> 
                \par 
l.6   \draw (0, 0) -- (0, \@ifnextchar1001)
                                          ;

What is the relevant difference between 01 and \@ifnextchar1001 in this case? How can I make this – or a similar construct – work as intended?

8
  • On another question, egreg pointed out that the XC@ prefix suggests that the problem might stem from within xcolor. Hence the color tag. Jan 22, 2017 at 1:45
  • For anyone interested: The problem I was trying to solve when walking into this gotcha was removing leading zeroes so TikZ would not try to parse them as octal. Jan 22, 2017 at 1:45
  • 1
    A lot of stuff is triggered by \begin{document}. It is good practice to make sure the cat codes are what LaTeX expects when that stuff gets executed. Hence, if you change them in the preamble, you change them back. If you change them in the document, you change them back before \end{document}. But you shouldn't usually change them in the document directly, of course.
    – cfr
    Jan 22, 2017 at 4:13
  • Why don't you either use simple macro or use PGF's maths stuff?
    – cfr
    Jan 22, 2017 at 4:14
  • 1
    @HermannDöppes Showing a call of \@ifnextchar1001 is not the best way to explain the problem you have. Yes, the ultimate reason is that \futurelet is involved, but that's all.
    – egreg
    Jan 22, 2017 at 9:34

2 Answers 2

5

\@ifnextchar is not expandable because of its internal use of \futurelet. A node name must be expandable, it is internally used inside \csname ...\endcsname.

If you just want to compare simple digits, then a test using the normal macro argument parsing is sufficient:

\documentclass{minimal}
\usepackage{tikz}

% \IfNextChar
% #1: the char for testing
% #2: code for true
% #3: code for false
% #4: next char
\makeatletter
\newcommand{\IfNextChar}[4]{%
  \ifx#1#4\@empty\@empty
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {#2}{#3}%
}
\makeatother

\begin{document}
\begin{tikzpicture}
    \node (\IfNextChar1001) at (0, 0) {};
\end{tikzpicture}
\end{document}

The same applies to the usage of \@ifnextchar as coordinate.

3
  • Also TikZ has its own \pgfutil@ifnextchar
    – percusse
    Jan 22, 2017 at 10:02
  • 1
    @percusse \pgfutil@ifnextchar does not change anything, it is quite the same as \@ifnextchar. I assume it is defined to get compatibility to other formats, namely plain TeX, than LaTeX that defines \@ifnextchar. Jan 22, 2017 at 10:07
  • Yes, I just mentioned it because it has very little cleaner syntax
    – percusse
    Jan 22, 2017 at 11:18
1

You can just convert the number from base 10 to base 10 using PGF math. Maybe overkill, maybe not.

\documentclass{article}
\usepackage{tikz}
\begin{document}
\pgfmathbasetodec{\myconvresult}{001}{10}
\pgfmathsetmacro\myresult{\myconvresult+1}\myresult

\pgfmathbasetodec{\myconvresult}{0214}{10}
\pgfmathsetmacro\myresult{\myconvresult+1}\myresult

\pgfmathbasetodec{\myconvresult}{000035}{10}
\pgfmathsetmacro\myresult{\myconvresult+1}\myresult

\pgfmathbasetodec{\myconvresult}{301}{10}
\pgfmathsetmacro\myresult{\myconvresult+1}\myresult
\end{document}

arithmetic in base 10

I'm surprised if there isn't a setting for this somewhere ....

5
  • While this solves my original problem, it does not answer the question. (And I'm surprised I didn't find this. Need to step up my searching game.) Jan 22, 2017 at 4:35
  • Well, TikZ essentially defines its own parser, so using anything non-PGF low-level to parse things in that environment is likely to be fraught in various ways. And I don't think regular code would work in place as you're using it, even without the cat-code stuff. When you say \begin{tikzpicture}, you trigger code which sets the cat codes to what TikZ expects, so any changes you've made prior to that are not going to make any difference. Look at the utility code for PGF to see what I mean. So you need to use a macro or something here, I think.
    – cfr
    Jan 22, 2017 at 4:48
  • And you did say you failed to find a simpler solution ...
    – cfr
    Jan 22, 2017 at 4:51
  • So, the real answer is “TikZ is magic and we can't tell which macro will work where. Just don't do it.”? Jan 22, 2017 at 4:58
  • 1
    No, but what you do here needs to play by the rules of PGF/TikZ. You need to take account of how it is parsing the input and can't assume that stuff is being parsed simply and directly by TeX/LaTeX, because it is not. This is why things like Babel can cause havoc if the language uses active short-hands and you have to take special precautions e.g. turning short-hands off inside TikZ pictures etc.
    – cfr
    Jan 22, 2017 at 14:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .