5

I have defined my own figure command using xkeyval and I want to pass arguments for the nested \includegraphics as one of its keyvalues (maybe I stripped too much code, but I hope you get the idea):

\makeatletter
  \define@key[foo]{bar}{options}{\def\FooBarOptions{#1}}
  \define@key[foo]{bar}{label}{\def\FooBarLabel{#1}}
  \define@key[foo]{bar}{caption}{\def\FooBarCaption{#1}}
\makeatother

%\MySpecialFigure[keyvals]{filename}
\newcommand{\MySpecialFigure}[2][]{%
  \begingroup
    \setkeys[foo]{bar}{options={}, label={}, caption={}}
    \setkeys[foo]{bar}{#1}

    \begin{figure}
      \includegraphics[\FooBarOptions]{#2}
      \caption{\FooBarCaption}
      \label{\FooBarLabel}
    \end{figure}
  \endgroup
}

I want to use it like:

\MySpecialFigure[options={width=0.5\textwidth, draft}, 
                 label={fig:label},
                 caption={My Caption}]
{my-pic.png}

Because of the braces around the options, the whole block gets parsed as one value at \includegraphics and behaves like:

\includegraphics[{width=0.5\textwidth, draft}]{my-pic.png}

I get error:

Package xkeyval Error:'width=0.5\textwidth, draft' undefined in families 'Gin'

I tried

  \define@key[foo]{bar}{options}{\edef\FooBarOptions{#1}}

but that wouldn' strip the braces either.

How can I solve this?

5

You need to expand the \FooBarOptions before you feed it to \includegraphics, otherwise it is taken as one key. This has nothing to do with an extra layer of braces.

Turning

\includegraphics[\FooBarOptions]{#2}

into

\expandafter\includegraphics\expandafter[\FooBarOptions]{#2}

should fix it.

  • It works like that. Why do I need expandafter twice? I tried both \expandafter\includegraphics[\FooBarOptions]{#2} and \includegraphics\expandafter[\FooBarOptions]{#2} – B3ret Apr 14 '11 at 10:39
  • @B3ret: An \expandafter "jumps" over the next token (e.g. macro), so the first one jumps over \includegraphics and would expand [ if the second one is not there. This one then jumps over the [ and expands \FooBarOptions. One way to avoid this is to define the [ ] as part of \FooBarOptions: \def\FooBarOptions{[#1]}. Then you can use \expandafter\includegraphics\FooBarOptions{#2}. However, \includegraphics\expandafter[\FooBarOptions]{#2} would make \includegrpahics be expanded first and then take \expandafter` as first mandatory argument, which causes of course trouble. – Martin Scharrer Apr 14 '11 at 10:42

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.