Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have the following piece of code

\documentclass{article}
\usepackage{tikz}
\def\pos{5,5}    
\begin{document}
 \begin{tikzpicture}    
  \node (b)  at (0,0) {test};
  \node (a) \ifx\pos\pgfutil@empty\else at(\pos)\fi {something};
 \end{tikzpicture}
\end{document}

I want to test if the macro \pos holds a position or not and in case it does I want to use it to print the node. However, when I compile the example above I get some errors in the way of:

Package tikz Error: A node must have a (possibly empty) label text.

Use of \@next doesn't match its definition.

What am I doing wrong? Or in which way can I achieve my goal of testing the macro for display?

share|improve this question
    
    
@DavidCarlisle The error is raised before \pgfutil@empty is examined, but of course the @ problem is relevant anyway. –  egreg Feb 9 '12 at 9:33
add comment

2 Answers 2

up vote 2 down vote accepted

To answer the part:

Or in which way can I achieve my goal of testing the macro for display?

Here's a method using pgfkeys to define a style tripos (with apologies to any Cambridge graduates present) which examines \pos to see if it is empty or not, and if not then it uses \pgfkeys to call the at key to set the node's position.

\documentclass{article}
\usepackage{tikz}
\def\pos{5,5}    

\tikzset{tripos/.code={%
    \unless\ifx\pos\empty
    \pgfkeys{/tikz/at=(\pos)}
    \fi
  }
}

\begin{document}
 \begin{tikzpicture}    
  \node (b)  at (0,0) {test};
  \node[tripos] (a) {something};
 \end{tikzpicture}
\end{document}

(As David Carlisle notes in his comment on your question, using the @ requires \makeatletter ... \makeatother wizardry. As you're using LaTeX, we can test against \empty instead of \pgfutil@empty and so avoid this issue.)

share|improve this answer
add comment

When TikZ looks for an at specification after \node (a), it doesn't expand tokens. So in your case it finds \ifx which it doesn't like.

If you really need such a test, the following hack works:

\begin{tikzpicture}
  \node (b)  at (0,0) {test};
  \begingroup\edef\x{\endgroup\noexpand\node (a) \ifx\pos\empty\else at(\pos)\fi}
  \x {something};
\end{tikzpicture}

as it expands the conditional before TikZ can see \node.

Note that you can't use \pgfutil@empty unless you set \makeatletter before the tikzpicture environment (it seems overkill to me).

share|improve this answer
    
I don't mean to be overly critical, and this is a nice showcase of a clever trick, but is the \begingroup thing really necessary? So what if another macro name gets defined, or \x gets overwritten? It seems more instructive to give the minimal effective code performing "compute first, then expand the result". –  Ryan Reich Feb 9 '12 at 9:37
    
With this code, you're sure that nothing will be overwritten. The only disallowed tokens are \noexpand\x in the replacement text, which wouldn't be meaningful anyway. –  egreg Feb 9 '12 at 9:47
    
Thanks for your comments. However, you say "if you really need such a test," is there any other way to achieve the same result but in a different way? –  adn Feb 9 '12 at 11:01
    
@egreg Even \noexpand\x can be used in the replacement text without trouble. The definition of \x that you created only lives from the end of the \edef to the end of the group, i.e., just long enough to expand that \x once. –  Bruno Le Floch Feb 9 '12 at 11:24
    
@BrunoLeFloch I had this doubt, indeed. Thanks. –  egreg Feb 9 '12 at 11:27
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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