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'm trying to create some TikZ commands that use key value options. Using the following link: How to create a command with key values? I was able to declare some commands, but now I'm stuck.

As a MWE consider:

\documentclass{article}
\usepackage{keyval}
\usepackage{tikz}
\usepackage{pgfkeys}

\makeatletter

% using keyval package
\define@key{cutkv}{label}{\def\cutkv@label{#1}}
\define@key{cutkv}{bend}{\def\cutkv@bend{#1}}
\setkeys{cutkv}{label={},bend={}}
\newcommand{\cutkv}[3][]{
  \begingroup
  \setkeys{cutkv}{#1}
  \draw[->] (#2) to[\cutkv@bend] node{\cutkv@label} (#3);
  \endgroup
}

% using pgfkeys package
\pgfkeys{
  /cutpgf/.is family, /cutpgf,
  default/.style =
  {label = ,
   bend = },
  label/.estore in = \cutpgf@label,
  bend/.estore in = \cutpgf@bend,
}
\newcommand{\cutpgf}[3][]{
  \pgfkeys{/cutpgf, default, #1}
  \draw[->] (#2) to[\cutpgf@bend] node{\cutpgf@label} (#3);
}
\makeatother

\begin{document}
\begin{tikzpicture}
  \cutkv[label=1]{0,0}{3,5}
  \cutkv[label=2,bend={bend right}]{1,4}{7,2}
  \cutkv[label=3,bend={bend right=10}]{6,0}{5,4}
\end{tikzpicture}

\begin{tikzpicture}
  \cutpgf[label=1]{0,0}{3,5}
  \cutpgf[label=2,bend={bend right}]{1,4}{7,2}
  \cutpgf[label=3,bend={bend right=10}]{6,0}{5,4}
\end{tikzpicture}
\end{document}

The first and the second call of the \cut command work fine, but in the third call the option bend right=10 is not passed correctly. At least, I don't understand the problem there.

I also tried the approach with pgfkeys, as mentioned in the first answer of the above post, but that didn't change anything.

edit: I added the version with pgfkeys to the MWE.

Any help is very much appreciated. Thanks.

share|improve this question
2  
The pgfkeys approach is different to keyval or xkeyval package, they do not co-operate, unfortunately. –  Christian Hupfer Feb 26 at 14:50
    
As I said, I also tried it with pgfkeys instead of keyval, but ended up with the same problem. –  stephan boehme Feb 26 at 14:53
    
I tried your approaches, they fail too. I believe, the problem is quite similar to the one I posed in a question some weeks ago, perhaps the solution Joseph gave there is the key (sic!) to the problem: <tex.stackexchange.com/questions/152020/…; -- in my point of view the source of the error lies in the double '=' characters, one as the outer key assignment, the other one as the inner key assignment of the pgfkeys –  Christian Hupfer Feb 26 at 15:43
    
I thought {...} would take care of that, but you might be right, adding a list of options like opt={thick,dashed} is not working neither. –  stephan boehme Feb 26 at 16:06
1  
@Christian Yes, same issue but here \expandafter is tricky so I've used \edef in an answer –  Joseph Wright Feb 26 at 16:52

1 Answer 1

up vote 6 down vote accepted

As suggested in a comment, this is nothing to do with the choice of keyval method but is instead due to the fact that keyval processors do not expand their input (in general). You need to force expansion, here probably easiest to do using \edef:

\documentclass{article}
\usepackage{keyval}
\usepackage{tikz}
\usepackage{pgfkeys}

\makeatletter

% using keyval package
\define@key{cutkv}{label}{\def\cutkv@label{#1}}
\define@key{cutkv}{bend}{\def\cutkv@bend{#1}}
\setkeys{cutkv}{label={},bend={}}
\newcommand{\cutkv}[3][]{
  \begingroup
  \setkeys{cutkv}{#1}
  \begingroup
    \edef\x
    {%
      \endgroup
      \noexpand\draw[->] (#2) to[\cutkv@bend] node{\cutkv@label} (#3);
    }\x
  \endgroup
}

% using pgfkeys package
\pgfkeys{
  /cutpgf/.is family, /cutpgf,
  default/.style =
  {label = ,
   bend = },
  label/.estore in = \cutpgf@label,
  bend/.estore in = \cutpgf@bend,
}
\newcommand{\cutpgf}[3][]{%
  \pgfkeys{/cutpgf, default, #1}%
  \begingroup
    \edef\x{%
      \endgroup
      \noexpand\draw[->] (#2) to[\cutpgf@bend] node{\cutpgf@label} (#3);
    }\x
}
\makeatother

\begin{document}
\begin{tikzpicture}
  \cutkv[label=1]{0,0}{3,5}
  \cutkv[label=2,bend={bend right}]{1,4}{7,2}
  \cutkv[label=3,bend={bend right=10}]{6,0}{5,4}
\end{tikzpicture}

\begin{tikzpicture}
  \cutpgf[label=1]{0,0}{3,5}
  \cutpgf[label=2,bend={bend right}]{1,4}{7,2}
  \cutpgf[label=3,bend={bend right=10}]{6,0}{5,4}
\end{tikzpicture}
\end{document}

In both cases, the idea is that the \draw line needs to have the full expansion of your variables: by using \edef I don't have to worry about carefully counting tokens for \expandafter.

share|improve this answer
    
Thank you very much. I tried your solution and extended it a bit to my needs and it works perfectly. –  stephan boehme Feb 27 at 9:21
    
Now, I found some unwanted side effects with \noexpand. If I change the drawcommand to \noexpand\draw[->] (#2) to[\cutkv@bend] node{\tiny \cutkv@label} (#3); I get errors, I can't solve. –  stephan boehme Feb 27 at 15:07
    
@stephanboehme Expansion is tricky: most LaTeX2e commands cannot be safely used inside \edef. Here, you'll need a \noexpand before \tiny to make it work. –  Joseph Wright Feb 27 at 16:22
    
Thanks again, it's working nicely now. And even with not completely understanding the expansion-\edef-\noexpand-issue, I get a feeling for it :) –  stephan boehme Feb 27 at 16:54

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.