2

Suppose I want to expand a macro argument to a tikz command a single time. If this was a normal macro defined with braces I'd know how to use expandafter to do it but I don't know where to put them with a tikz command since I'm not sure how it parses it's command and it's not nicely broken up with braces. Do I need expandafters for each token that appears in the tikz command before the argument I want expanded?

In particular, how would I define the macro \drawnode below so it expands it's argument once before inserting it. I'm fine with solutions based on something besides expandafter like edef.

\NewDocumentCommand{\drawnode}{m} {\node[draw,circle,minimum size=2.2mm,black] (foo) at (0,0) #1}

In other words, how would I change \drawnode to made the following code work.

\documentclass{standalone}

\usepackage{unicode-math}
    \setmainfont{XITS}
    \setmathfont{XITS Math}
    \setmathfont{XITS Math}[range={\mathscr,\mathbfscr}]
    \setmathfont{XITS Math}[range={\mathcal,\mathbfcal},StylisticSet=1]
\usepackage{tikz}

\NewDocumentCommand{\drawnode}{m} {\node[draw,circle,minimum size=2.2mm,black] (foo) at (0,0) #1}
\newcommand{\drawagain}{; \node (rect) at (4,2) [draw,thick,minimum width=2cm,minimum height=2cm] {};}

\begin{tikzpicture}
   \drawnode{\drawagain}
\end{tikzpicture}
\end{document}

4
  • 1
    Your example seems to be poorly constructed. Since #1 is the last thing in the definition of \drawnode (which is defined with four arguments for some reason, but I guess that's a typo), you could just make it take no arguments at all and do \expandafter\drawnode\drawagain. However, this would still not work with your example, not because of some expansion issue, but because you did not provide any node text. Could you change your MWE to something that more clearly shows what you want to do?
    – schtandard
    Feb 9 at 17:41
  • oops, sorry, yes I was simplifying ….the real case is pretty complicated and I have some arguments that are built up with for loops. I've fixed the newcommand bit but basically I just want to know how to expand an argument once that I've embedded somewhere inside a long tikz command. Feb 9 at 17:41
  • Also, if everything you want to do is styling your nodes, you should do that using TikZ styles instead of commands.
    – schtandard
    Feb 9 at 17:43
  • Yes, I just choose the simplest example I could make which illustrated a case where it only works if I expand the argument once. I presume you are saying that with just styling tikz nodes I could get away with just fully expanding everything with edef? Feb 9 at 17:46
3

The issue is not one of expansion, but rather a syntax error: a missing {} label (that would be text inside the circle) at the end of \drawnode, prior to #1.

If you follow the train of comments below the answer, you will see a discussion of expansion in the context of tikz and pgf. The issue often becomes, I have found, using expansion to break out of the local scope of a non-expandable \foreach loop.

\documentclass{standalone}

%\usepackage{unicode-math}
%    \setmainfont{XITS}
%    \setmathfont{XITS Math}
%    \setmathfont{XITS Math}[range={\mathscr,\mathbfscr}]
%    \setmathfont{XITS Math}[range={\mathcal,\mathbfcal},StylisticSet=1]
\usepackage{tikz}

\NewDocumentCommand{\drawnode}{m} {%
  \node[draw,circle,minimum size=2.2mm,black] (foo) at (0,0) {} #1 }
\newcommand{\drawagain}{; \node (rect) at (4,2) 
  [draw,thick,minimum width=2cm,minimum height=2cm] {};}

\begin{document}

\begin{tikzpicture}
  \drawnode{\drawagain}
\end{tikzpicture}
\end{document}

enter image description here

5
  • That was a typo created when I simplified this for posting but I don't understand why this doesn't produce the same kind of error as when I try to build a tikz matrix using a macro containing a \foraeach. Shouldn't the expansion result in: "\node[draw,circle,minimum size=2.2mm,black] (foo) at (0,0) {} \drawagain" and then tikz should throw an error when it can't find ; ending the command? Feb 11 at 9:35
  • 1
    Ok, maybe a better way to get the answer I'm looking for is just to ask whether tikz will fully expand any commands it encounters while trying to parse a command or does it only expand once or what's the deal? Feb 11 at 9:37
  • 1
    @PeterGerdes I looked through my prior answers to see where I may have needed to pre-expand things in the context of tikz. The few I came across included: expand the argument to \pgfkeys tex.stackexchange.com/questions/368736/…, and using expansion to globally save \color@pgfstrokecolor in tex.stackexchange.com/questions/320819/… Feb 11 at 10:05
  • 1
    @PeterGerdes I also found an expansion needed to get fractions inside of a pgf-pie chart: tex.stackexchange.com/questions/456368/… . A good search key to learn more would be tikz \expandafter. I would also add that \foreach requires pre-expansion if you need to break the result out of the local group, for example here: tex.stackexchange.com/questions/567722/… Feb 11 at 10:10
  • 1
    Ok, I fhink I see where I got confused. I thought the reason you can't build a tikz matrix using the foreach inside the matrix command as in this answer was something about tikz commands needing to be already expanded. I now believe I was wrong and the problem is that \foreach isn't expandable. Thanks for helping me figure out what I was confused about. Let me know if I should delete the question since it's kinda confused. Feb 11 at 10:16

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.