3

How can I resolve an xkeyvalue from a definition? The code

\documentclass{article}
\usepackage{xkeyval}

\define@key{mykeys}{foo}[foo-default]{\def\x{Key 'foo' does nothing}}
\define@key{mykeys}{bar}[bar-default]{}
\def\KEYS{foo,bar=key}

\begin{document}
\setkeys{mykeys}{\KEYS}
\end{document}

fails because foo,bar=key is not recognized as two keys, but only as one key. In other words, xkeyval does not recognize the comma between the keys foo and bar=key. How can I make xkeyval identify the comma correctly?

2
  • Welcome to TeX.sx! Commented Mar 11, 2013 at 0:07
  • Without a default value, foo can't be set without a user value. So I inserted defaults for foo and bar.
    – Ahmed Musa
    Commented Mar 11, 2013 at 1:16

2 Answers 2

3

\setkeys does not expand its second argument, but the error message does so sometimes it's puzzling.

You can define a \setkeysexpanded command:

\newcommand{\setkeysexpanded}[2]{%
  \expandafter\setkeysexpandedaux\expandafter{#2}{#1}}
\newcommand{\setkeysexpandedaux}[2]{%
  \setkeys{#2}{#1}}

Then

\setkeysexpanded{mykeys}{\KEYS}

will work.

The double argument switching is to ease the use of \expandafter.

4
  • Thanks! I already thought my problem had to do with expansions, but I cound not figure it out correctly. Would it also be possible to achieve this without any auxiliary commands? Commented Mar 11, 2013 at 0:02
  • @SimonReich One could redefine \setkeys, but I wouldn't recommend it. Better keeping the things well separated. However, \setkeysexpanded works also with normally specified options.
    – egreg
    Commented Mar 11, 2013 at 0:04
  • Alright, this solution works perfectly well. Commented Mar 11, 2013 at 0:04
  • @SimonReich Welcome to TeX.sx!
    – egreg
    Commented Mar 11, 2013 at 0:05
1

Please accept egreg's answer. Another approach is to define a special key set list that you then use to set a key-value list:

\documentclass{article}
\usepackage{xkeyval}
\makeatletter
\define@key{mykeys}{set list}{%
  \edef\reserved@a{\noexpand\XKV@setkeys[]{\unexpanded\expandafter{#1}}}%
  \reserved@a
}
\define@key{mykeys}{foo}[foo-default]{%
  \edef\x{Key 'foo' with value '\detokenize{#1}' does nothing}%
}
\define@key{mykeys}{bar}[bar-default]{%
  \edef\x{Key 'bar' with value '\detokenize{#1}' does nothing}%
}
\def\kvlist{foo,bar=bar-value}
\setkeys{mykeys}{set list=\kvlist}
\makeatother
\begin{document}
x
\end{document} 

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .