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 try to write a command that accepts options, using pgfkeys. Unknown keys are collected in a style, that I try to use as global options for a tikzpicture environement. A minimal example would be:

\documentclass{article}
\usepackage{tikz}

\newif\ifsquare

\pgfqkeys{/test}{%
 square/.is if=square,
 square/.default=true,
% collect unknown keys in style 'remainingkeys':
 .unknown/.code={%
  \let\currname\pgfkeyscurrentname%
  \let\currval\pgfkeyscurrentvalue%
  \ifx#1\pgfkeysnovalue%
   \pgfqkeys{/tikz}{remainingkeys/.append style={\currname}}%
  \else%
   \pgfqkeys{/tikz}{remainingkeys/.append style={\currname=\currval}}%
  \fi%
 }%
}

\newcommand\myfigure[1][]{
% initialize:
 \pgfqkeys{/tikz}{remainingkeys/.style={}}
 \pgfqkeys{/test}{square}
% set user keys:
 \pgfqkeys{/test}{#1}
 \begin{tikzpicture}[/tikz/remainingkeys]
  \ifsquare
   \fill (0,0)rectangle(1,1);
  \else
   \fill (0,0)rectangle(1.2,.8);
  \fi
 \end{tikzpicture}
}

\begin{document}

 \myfigure[square,rotate=45]                % rotated 45 degs; ok
 \myfigure[square,fill=red]                 % red; ok
 \myfigure[square,rotate=45,fill=red]       % red, but doesn't rotate
 \myfigure[square=false]                    % not square
 \myfigure[square=false,fill=red,rotate=45] % not square, not red and rotated 90 degs!

\end{document} 

The command \myfigure simply draws a square or rectangle, depending on the value of the 'square'-key. This key is handled correctly. All other options are handled by the .unknown/.code handler and collected into the style 'remainingkeys', which eventually is passed to \begin{tikzpicture}. The first call of \myfigure indeed draws a square, and rotates it, but the third call doesn't! Somehow not all unknown keys are stored in 'remainingkeys'. In the fifth call even the rotation angle isn't right.

I tried a lot of things, but this is the best that I can come up with, at least without producing any TeX-errors. I'm doing something seriously wrong, but what? I'm dead in the water...

share|improve this question
    
Welcome to TeX.sx! A tip: you can use backticks ` to mark your inline code‌​. –  Martin Scharrer Jul 13 '11 at 10:06

1 Answer 1

up vote 3 down vote accepted

You need to expand the \currname and \currval values first. Otherwise you simply storing this macros which definitions will change. Therefore you loose all but the last option, which is repeated several times like seen in the double rotation in your example.

\documentclass{article}
\usepackage{tikz}

\newif\ifsquare

\pgfqkeys{/test}{%
 square/.is if=square,
 square/.default=true,
% collect unknown keys in style 'remainingkeys':
 .unknown/.code={%
  \let\currname\pgfkeyscurrentname%
  \let\currval\pgfkeyscurrentvalue%
  \ifx#1\pgfkeysnovalue%
   \pgfqkeys{/tikz}{remainingkeys/.append style/.expand once={\currname}}%
  \else%
   \pgfqkeys{/tikz}{remainingkeys/.append style/.expand twice={\expandafter\currname\expandafter=\currval}}%
  \fi%
 }%
}

\newcommand\myfigure[1][]{
% initialize:
 \pgfqkeys{/tikz}{remainingkeys/.style={}}
 \pgfqkeys{/test}{square}
% set user keys:
 \pgfqkeys{/test}{#1}
 \begin{tikzpicture}[/tikz/remainingkeys]
  \ifsquare
   \fill (0,0)rectangle(1,1);
  \else
   \fill (0,0)rectangle(1.2,.8);
  \fi
 \end{tikzpicture}
}

\begin{document}

 \myfigure[square,rotate=45]                % rotated 45 degs; ok
 \myfigure[square,fill=red]                 % red; ok
 \myfigure[square,rotate=45,fill=red]       % red, but doesn't rotate
 \myfigure[square=false]                    % not square
 \myfigure[square=false,fill=red,rotate=45] % not square, not red and rotated 90 degs!

\end{document} 

Result

share|improve this answer
    
Aha, it's the \let's that are causing this. I changed my .unknown/.code into this: .unknown/.code={% \ifx#1\pgfkeysnovalue% \expandafter\appendtostyle\expandafter{\pgfkeyscurrentname}% \else% \expandafter\appendtostyle\expandafter{\pgfkeyscurrentname=#1}% \fi% }% where \appendostyle is defined as follows: \def\appendtostyle#1{\pgfqkeys{/tikz}{remainingkeys/.append style={#1}}} This works. Many thanks! –  Mike Boldy Jul 13 '11 at 10:22
    
Your solution is better of course: no need to define an extra macro, that could get lost in the mess that my code usually is... Thank you, Martin –  Mike Boldy Jul 13 '11 at 10:34
    
@Mike: storing the \pgfkeyscurrentname etc. macros in an own macro using \let is actually a good thing, if you can't expand them directly. They might be overwritten by TiKZ before you use them again. If this answer helped you please consider accepting it as the official solution by clicking the tick mark to the upper left of it. Thanks. –  Martin Scharrer Jul 13 '11 at 10:56

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.