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?

  • On another question, egreg pointed out that the XC@ prefix suggests that the problem might stem from within xcolor. Hence the color tag. – Hermann Döppes Jan 22 '17 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. – Hermann Döppes Jan 22 '17 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 '17 at 4:13
  • Why don't you either use simple macro or use PGF's maths stuff? – cfr Jan 22 '17 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 '17 at 9:34
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.

  • Also TikZ has its own \pgfutil@ifnextchar – percusse Jan 22 '17 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. – Heiko Oberdiek Jan 22 '17 at 10:07
  • Yes, I just mentioned it because it has very little cleaner syntax – percusse Jan 22 '17 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 ....

  • 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.) – Hermann Döppes Jan 22 '17 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 '17 at 4:48
  • And you did say you failed to find a simpler solution ... – cfr Jan 22 '17 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.”? – Hermann Döppes Jan 22 '17 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 '17 at 14:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.