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 am trying to use TikZ together with a macro that I defined via \NewDocumentCommand (for multiple optional arguments), but it doesn't behave as expected. TikZ is giving up on the path instead of working with the macro expansion.

Minimal example:

\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}
\usetikzlibrary{positioning}

\NewDocumentCommand{\myEdge}{O{} O{auto} m}{edge [#1] node [#2] {#3}}

\begin{document}
% This works
\begin{tikzpicture}
  \node (test1) {test1};
  \node (test2) [right=of test1] {test2} edge [] node [auto] {test3} (test1);
\end{tikzpicture}

% This does not
\begin{tikzpicture}
  \node (test1) {test1};
  \node (test2) [right=of test1] {test2} \myEdge{test3} (test1);
\end{tikzpicture}
\end{document}

Output:

! Package tikz Error: Giving up on this path. Did you forget a semicolon?.

See the tikz package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.19 ...e (test2) [right=of test1] {test2} \myEdge
                                                  {test3} (test1);

Edit: The answer given by @Werner works beautifully when only using the macro with the required argument, or not using it more than once per path. But the following example still fails:

\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}
\usetikzlibrary{positioning}

\DeclareExpandableDocumentCommand{\myEdge}{O{} O{auto} m}{edge [#1] node [#2] {#3}}
\begin{document}
% This works
\begin{tikzpicture}
  \node (node1) {node1};
  \node (node2) [right=of node1] {node2};
  \node (node3) [right=of node2] {node3} edge [bend left] node [right] {edge1} (node2) edge [] node [auto] {edge2} (node1);
\end{tikzpicture}

% This does not
\begin{tikzpicture}
  \node (node1) {node1};
  \node (node2) [right=of node1] {node2};
  \node (node3) [right=of node2] {node3} \myEdge[bend left][right]{edge1} (node2) \myEdge{edge2} (node1);
\end{tikzpicture}
\end{document}

The error:

! Package tikz Error: Giving up on this path. Did you forget a semicolon?.

See the tikz package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.19 ...left][right]{edge1} (node2) \myEdge{edge2}
                                                   (node1);

I feel like I am missing some fundamental understanding of how either xparse generates those macros, or how TikZ parses the path.

share|improve this question
    
If you place your last nonworking line replacing the dots \edef\temp{\noexpand....}\temp it works and shows that it is still an expansion issue. –  percusse Oct 30 '12 at 7:53
add comment

1 Answer

up vote 6 down vote accepted

The desired output is achieved using \DeclareExpandableDocumentCommand:

\DeclareExpandableDocumentCommand{\myEdge}{O{} O{auto} m}{edge [#1] node [#2] {#3}}

As mentioned, this is only a partial solution since it only works sometimes, maybe. The requirement that the command be expandable stems from the fact that tikz is building a path on-the-go, and therefore scans your input, assembling it into pieces. If it finds a piece in the path generation it doesn't understand, it assumes you should have actually closed the path (with a trailing ;). So, since \myEdge isn't part of the tikz path lingo, it has a problem interpreting it. This is a typical expansion issue.

share|improve this answer
    
Not part of the initial question, but: Is there a different, less fragile way to do this then? And thanks for the answer :-) –  dominikh Oct 30 '12 at 12:38
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.