2

I want to use kvoptions for a package, with a string option, and I want unknown options to be used as values for that string option. Like this:

\ProvidesPackage{kvo}[2020/10/20 v 0.01 playing with kvoptions]
\RequirePackage{kvoptions}
\SetupKeyvalOptions{family=cdr,prefix=cdr@,setkeys=\kvsetkeys}

\DeclareStringOption{bla} \AddToKeyvalOption{bla}{ \immediate\write16{Option bla set to #1 which is the same as \cdr@bla. *} } \DeclareDefaultOption{ \immediate\write16{Default option: \CurrentOption} \kvsetkeys{cdr}{bla=\CurrentOption} \immediate\write16{Now cdr@bla is \cdr@bla} } \ProcessKeyvalOptions

So I would expect that \usepackage[toto]{kvo} would set \cdr@bla to toto. Testing it:

\documentclass{article}
\usepackage[toto]{kvo}
\begin{document}
\makeatletter
\immediate\write16{And now cdr@bla is \cdr@bla.}
\makeatother
\end{document}

and the relevant lines from my output are like this:

Default option: toto
Option bla set to toto which is the same as toto. ***
Now cdr@bla is toto
And now cdr@bla is .

What is happening that loses the value of \cdr@bla? What would be the right way to achieve what I want, i.e. transfer a Default Option to the setting of a String Option?

I know that I can say \xdef\cdr@bla{\CurrentOption} and that works, but if setting option bla has side-effects that would mean repeating code, or calling the same macro from both places, which I would find less readable.

Vincent Beffara
  • 246
  • 1
  • 11
  • \write16 isn't a good debugging tool here, as it will expand all commands. If you add a \show\cdr@bla in your package you will see that the command contains only \CurrentOption and \CurrentOption changes later. I would do something like \newcommand\mysetbla[1]{\kvsetkeys{cdr}{bla=#1}} \DeclareDefaultOption{\expandafter\mysetbla\expandafter{\CurrentOption}} (or use expl3 for a similar effect.) – Ulrike Fischer Mar 19 '21 at 13:55
  • Ahhh ! ok everything is much clearer now. Thanks! – Vincent Beffara Mar 19 '21 at 14:15
  • What should happen if multiple undefined options get used? – Skillmon Mar 19 '21 at 15:24
  • Presumably the side-effects for each of them would be applied in the order that they appear in the list and the final value of \cdr@bla would be the last undefined option, at least that would be the least surprising outcome for the user. In my use case I don't really expect this to happen though. – Vincent Beffara Mar 19 '21 at 15:34
  • As I said defining DefaultOption to do \xdef\cdr@bla{\CurrentOption} and putting the side effects after the \ProcessKeyvalOptions would work fine, I was just wondering if there was a more idiomatic way. – Vincent Beffara Mar 19 '21 at 15:36
  • I'd opt for \DeclareDefaultOption{\let\cdr@bla\CurrentOption} in that case, no need to go through the key=value parser for this if it's just a string option and you don't really need the \AddToKeyvalOption* stuff. – Skillmon Mar 22 '21 at 11:00
  • That seems to be the easiest way, indeed. I wanted to forward the call because I foresee cases where there is non-trivial stuff to perform using \AddToKeyvalOption*, typically loading a .clo file which would need to be done before parsing the next options. – Vincent Beffara Mar 22 '21 at 13:32

0 Answers0