# A package template using xkeyval?

I would like to write a package offering a number of commands. The package should accept options, and some of these options should be available as command options. Usage should be as follows:

...
\usepackage[optA=val1,optB=val2]{mypackage}
\begin{document}
\mycommand[optB=val3]
...

It seems as if the xkeyval package can do that, but I am not sure how this should be done exactly.

-

Let me provide a simple (but full) example:

\ProvidesPackage{myemph}[2011/03/12 v1.0 a test package]

\providecommand\my@emphstyle{\em}

% Note that the argument must be expandable,
% or use xkvltxp package before \documentclass (see manual of xkeyval)
\RequirePackage{xkeyval}
\DeclareOptionX{style}{%
\def\my@emphstyle{\csname my@style@#1\endcsname}}
% predefined styles
\providecommand\my@style@default{\em}
\providecommand\my@style@bold{\bfseries}

\ProcessOptionsX

% For simple key-value commands, keyval would suffie
\define@key{myemph}{code}{%
\def\my@emphstyle{#1}}
\define@key{myemph}{style}{%
\def\my@emphstyle{\csname my@style@#1\endcsname}}
\newcommand\setemph[1]{%
\setkeys{myemph}{#1}}

\renewcommand\emph[1]{%
{\my@emphstyle #1}}

\endinput

Test file:

\documentclass{article}
\usepackage[style=default]{myemph}

\begin{document}
Something \emph{important}

\setemph{style=bold}
Something \emph{important}

\setemph{code=\Large\sffamily}
Something \emph{important}
\end{document}

-
I have read this article en.wikibooks.org/wiki/LaTeX/Macros which lead me to this post. Can you explain what \providecommand\my@emphstyle{\em} does? I know the command \providecommand but I cant find what the @means. Also, if I do a regular short document and including just this line in the preamble, my document wont compile. – Adam Feb 4 '14 at 23:19
@Adam: You may read \@ and @ in macro names – Leo Liu Feb 5 '14 at 5:21
@Adam: See also, for example, What do \makeatletter and \makeatother do? – Leo Liu Feb 5 '14 at 5:23

Accepting key-value input can be done using a number of packages, and the general approach is the same for all of them: I covered this in some detail in a TUGboat article. Essentially, there are three things you need to do

1. Define one or more keys;
2. Tell LaTeX to process package options using these keys;

In the question, you've mentioned the xkeyval package, with others including kvoptions, pgfkeys (plus pgfopts) and the LaTeX3 keys system l3keys (plus l3keys2e). I have used all of these in the past, and I would favour pgfkeys (if you do not want to use LaTeX3) or the LaTeX3 keys implementation (if you are happy using expl3). The reason is that these two have in my opinion the best overall method for defining keys. (I should add that I wrote most of the LaTeX3 keys system, and this was based initially on the pgfkeys approach.)

As the question asks for an xkeyval approach, I will sketch one out here. First, of course, you'll need to load the package.

\usepackage{xkeyval}

This also loads the parent keyval package, which provides some of the basic mechaism. To define keys, the basic macro is \define@key:

\define@key{mypkg}{optA}{<code for optA>} % 'mypkg' is the 'family' for the keys
\define@key{mypkg}{optB}{<code for optB>}

Within the code, #1 will be the value passed to the key. You can define key types with richer validation (for example Boolean keys) using the various xkeyval macros. As I say, the xkeyval approach is rather dense, and I think 'one question per key type' might be best if you want more information!

The second stage is to process the package options. To do this, in place of \ProcessOptions you use \ProcessOptionsX<mypkg>. This will work through the package options, looking for a defined key for each one and executing the code it finds.

Finally, to define a macro to use the keys after package loading, you need \setkeys:

\newcommand\mymacro[1]{\setkeys{mypkg}{#1}}

What you should notice here is that key-value package options are just keys that are defined when the \ProcessOptionsX macro is used. So it is possible to define keys only as package options, then disable them by doing \defin@key again. It's also possible to define options that are only available after package loading, by simply placing \define@key after \ProcessOptionsX.

-
A small correction: they should be \define@key<mypkg>{optA}{<code for optA>} and \ProcessOptionsX<mypkg> – Leo Liu Mar 12 '11 at 8:01
@Leo: been a while since I used xkeyval: I'll update that. – Joseph Wright Mar 12 '11 at 8:21
@Leo: I'm sure I'm right on \define@key, as the syntax comes from the keyval package! – Joseph Wright Mar 12 '11 at 8:22
sorry I thought it was \DeclareOptionX – Leo Liu Mar 12 '11 at 10:39

An example with some code from the documentation

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}[12/03/2011]
\RequirePackage{xkeyval}
\DeclareOptionX{parindent}[20pt]{\setlength\parindent{#1}}
\ExecuteOptionsX{parindent=0pt}
\ProcessOptionsX\relax
% etc.
\endinput

\DeclareOptionX is equivalent to (thanks to Ahmed Musa for the correction)

\define@key{mypackage.sty}{parindent}[20pt]{\setlength\parindent{#1}}
-
You have mixed package and class calls. In your case, \DeclareOptionX is equivalent to \define@key{mypackage.sty}{parindent}[20pt]{\setlength\parindent{#1}}. – Ahmed Musa Aug 10 '12 at 12:50
@AhmedMusa Thanks for the correction. – Alain Matthes Aug 10 '12 at 14:29