From f68c66c2fd38fcd1146a01bbe28f58ed0efc6f79 Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Mon, 14 Aug 2006 00:00:58 +0000
Subject: oberdiek update to get kvoptions 2.2 (2aug06)

git-svn-id: svn://tug.org/texlive/trunk@1948 c570f23f-e606-0410-a88d-b1316a301751
---
 .../texmf-dist/source/latex/oberdiek/kvoptions.dtx | 2293 ++++++++++++++++++++
 1 file changed, 2293 insertions(+)
 create mode 100644 Master/texmf-dist/source/latex/oberdiek/kvoptions.dtx

(limited to 'Master/texmf-dist/source/latex/oberdiek/kvoptions.dtx')

diff --git a/Master/texmf-dist/source/latex/oberdiek/kvoptions.dtx b/Master/texmf-dist/source/latex/oberdiek/kvoptions.dtx
new file mode 100644
index 00000000000..66bfb7f615c
--- /dev/null
+++ b/Master/texmf-dist/source/latex/oberdiek/kvoptions.dtx
@@ -0,0 +1,2293 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2004, 2006 by Heiko Oberdiek <oberdiek@uni-freiburg.de>
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either
+% version 1.3 of this license or (at your option) any later
+% version. The latest version of this license is in
+%    http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of
+% LaTeX version 2003/12/01 or later.
+%
+% This work has the LPPL maintenance status "maintained".
+%
+% This Current Maintainer of this work is Heiko Oberdiek.
+%
+% This work consists of the main source file kvoptions.dtx
+% and the derived files
+%    kvoptions.sty, kvoptions.pdf, kvoptions.ins, kvoptions.drv,
+%    example-mycolorsetup.sty.
+%
+% Distribution:
+%    CTAN:macros/latex/contrib/oberdiek/kvoptions.dtx
+%    CTAN:macros/latex/contrib/oberdiek/kvoptions.pdf
+%
+% Unpacking:
+%    (a) If kvoptions.ins is present:
+%           tex kvoptions.ins
+%    (b) Without kvoptions.ins:
+%           tex kvoptions.dtx
+%    (c) If you insist on using LaTeX
+%           latex \install=y\input{kvoptions.dtx}
+%        (quote the arguments according to the demands of your shell)
+%
+% Documentation:
+%    (a) If kvoptions.drv is present:
+%           latex kvoptions.drv
+%    (b) Without kvoptions.drv:
+%           latex kvoptions.dtx; ...
+%    The class ltxdoc loads the configuration file ltxdoc.cfg
+%    if available. Here you can specify further options, e.g.
+%    use A4 as paper format:
+%       \PassOptionsToClass{a4paper}{article}
+%
+%    Programm calls to get the documentation (example):
+%       pdflatex kvoptions.dtx
+%       makeindex -s gind.ist kvoptions.idx
+%       pdflatex kvoptions.dtx
+%       makeindex -s gind.ist kvoptions.idx
+%       pdflatex kvoptions.dtx
+%
+% Installation:
+%    TDS:tex/latex/oberdiek/kvoptions.sty
+%    TDS:doc/latex/oberdiek/kvoptions.pdf
+%    TDS:doc/latex/oberdiek/example-mycolorsetup.sty
+%    TDS:source/latex/oberdiek/kvoptions.dtx
+%
+%<*ignore>
+\begingroup
+  \def\x{LaTeX2e}
+\expandafter\endgroup
+\ifcase 0\ifx\install y1\fi\expandafter
+         \ifx\csname processbatchFile\endcsname\relax\else1\fi
+         \ifx\fmtname\x\else 1\fi\relax
+\else\csname fi\endcsname
+%</ignore>
+%<*install>
+\input docstrip.tex
+\Msg{************************************************************************}
+\Msg{* Installation}
+\Msg{* Package: kvoptions 2006/06/01 v2.2 Connects package keyval with LaTeX options (HO)}
+\Msg{************************************************************************}
+
+\keepsilent
+\askforoverwritefalse
+
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2004, 2006 by Heiko Oberdiek <oberdiek@uni-freiburg.de>
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3 of this license or (at your option) any later
+version. The latest version of this license is in
+   http://www.latex-project.org/lppl.txt
+and version 1.3 or later is part of all distributions of
+LaTeX version 2003/12/01 or later.
+
+This work has the LPPL maintenance status "maintained".
+
+This Current Maintainer of this work is Heiko Oberdiek.
+
+This work consists of the main source file kvoptions.dtx
+and the derived files
+   kvoptions.sty, kvoptions.pdf, kvoptions.ins, kvoptions.drv,
+   example-mycolorsetup.sty.
+
+\endpreamble
+
+\generate{%
+  \file{kvoptions.ins}{\from{kvoptions.dtx}{install}}%
+  \file{kvoptions.drv}{\from{kvoptions.dtx}{driver}}%
+  \usedir{tex/latex/oberdiek}%
+  \file{kvoptions.sty}{\from{kvoptions.dtx}{package}}%
+  \usedir{doc/latex/oberdiek}%
+  \file{example-mycolorsetup.sty}{\from{kvoptions.dtx}{example}}%
+}
+
+\obeyspaces
+\Msg{************************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* file into a directory searched by TeX:}
+\Msg{*}
+\Msg{*     kvoptions.sty}
+\Msg{*}
+\Msg{* To produce the documentation run the file `kvoptions.drv'}
+\Msg{* through LaTeX.}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesFile{kvoptions.drv}%
+  [2006/06/01 v2.2 Connects package keyval with LaTeX options (HO)]
+\documentclass{ltxdoc}
+\usepackage{holtxdoc}
+\begin{document}
+  \DocInput{kvoptions.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{1488}
+%
+% \CharacterTable
+%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%   Digits        \0\1\2\3\4\5\6\7\8\9
+%   Exclamation   \!     Double quote  \"     Hash (number) \#
+%   Dollar        \$     Percent       \%     Ampersand     \&
+%   Acute accent  \'     Left paren    \(     Right paren   \)
+%   Asterisk      \*     Plus          \+     Comma         \,
+%   Minus         \-     Point         \.     Solidus       \/
+%   Colon         \:     Semicolon     \;     Less than     \<
+%   Equals        \=     Greater than  \>     Question mark \?
+%   Commercial at \@     Left bracket  \[     Backslash     \\
+%   Right bracket \]     Circumflex    \^     Underscore    \_
+%   Grave accent  \`     Left brace    \{     Vertical bar  \|
+%   Right brace   \}     Tilde         \~}
+%
+% \GetFileInfo{kvoptions.drv}
+%
+% \title{The \xpackage{kvoptions} package}
+% \date{2006/06/01 v2.2}
+% \author{Heiko Oberdiek\\\xemail{oberdiek@uni-freiburg.de}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% This package is intended for package authors who want to
+% use options in key value format for their package options.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \def\M#1{\texttt{\{}\meta{#1}\texttt{\}}}
+% \def\O#1{\texttt{[}\meta{#1}\texttt{]}}
+%
+% \section{Introduction}
+%
+% \subsection{The beginning}
+%
+% This package addresses class or package writers
+% that want to allow their users to specify options
+% as key value pairs, e.g.:
+% \begin{quote}
+% |\documentclass[verbose=false,name=me]{myclass}|\\
+% |\usepackage[format=print]{mylayout}|
+% \end{quote}
+% Prominent example is package \xpackage{hyperref},
+% probably the first package that offers this service.
+% It's \cs{ProcessOptionsWithKV} is often copied und
+% used in other packages, e.g. package \xpackage{helvet}
+% that uses this interface for its option \xoption{scaled}.
+%
+% However copying code is not the most modern software
+% development technique. And \xpackage{hyperref}'s
+% code for \cs{ProcessOptionsWithKV} was changed
+% to fix bugs. The version used in other packages
+% depends on the time of copying and the awareness
+% of \xpackage{hyperref}'s changes.
+% Now the code is sourced out into this package and
+% available for other package or class writers.
+%
+% \subsection{Overview}
+%
+% Package \xpackage{kvoptions} connects package
+% \xpackage{\emph{k}ey\emph{v}al}
+% with \LaTeX's package and class \emph{options}:
+% \begin{center}
+% \def\T#1{\bfseries #1}
+% \renewcommand{\arraystretch}{1.5}
+% \begin{tabular}{l|l|l}
+%   \T{Package \xpackage{keyval}}
+%   & \T{Package \xpackage{kvoptions}}
+%   & \T{\LaTeX\ kernel}
+%   \\
+% \hline
+%     \cs{define@key}
+%   &
+%     \renewcommand*{\arraystretch}{1}^^A
+%     \begin{tabular}[t]{@{}l@{}}
+%       \cs{DeclareVoidOption}\\
+%       \cs{DeclareStringOption}\\
+%       \cs{DeclareBooleanOption}\\
+%       \cs{DeclareComplementaryOption}\\
+%       \cs{DisableKeyvalOption}
+%     \end{tabular}
+%   & \cs{DeclareOption}
+%   \\
+% \hline
+%   & \cs{DeclareDefaultOption}
+%   & \cs{DeclareOption*}
+%   \\
+% \hline
+%   & \cs{ProcessKeyvalOptions}
+%   & \cs{ProcessOptions*}
+%   \\
+% \hline
+%   & Option \xoption{patch}
+%   &
+%     \renewcommand*{\arraystretch}{1}^^A
+%     \begin{tabular}[t]{@{}l@{}}
+%       Class/package\\
+%       option system
+%     \end{tabular}
+%   \\
+% \hline
+%   & \cs{SetupKeyvalOptions} &
+%   \\
+% \end{tabular}
+% \end{center}
+%
+% \hypersetup{bookmarksopenlevel=3}
+% \section{Usage}
+%
+% \subsection{Process options}
+%
+% \subsubsection{\cs{ProcessKeyvalOptions}}
+%
+% \begin{declcs}{ProcessKeyvalOptions}\,\M{family}\\
+%   \cs{ProcessKeyvalOptions} \*
+% \end{declcs}
+% This command evaluates the global or local options of
+% the package that are defined with \xpackage{keyval}'s
+% interface within the family \meta{family}. It acts the
+% same way as \LaTeX's \cs{ProcessOptions*}. In a package
+% unknown global options are ignored, in a class they
+% are added to the unknown option list. The known global
+% options and all local options are passed to \xpackage{keyval}'s
+% \cs{setkeys} command for executing the options.
+% Unknown options are reported to the user by an error.
+%
+% If the family name happens to be the same as the name
+% of the package or class where \cs{ProcessKeyvalOptions}
+% is used or the family name has previously been setup by
+% \cs{SetupKeyvalOptions}, then \cs{ProcessKeyvalOptions}
+% knows the family name already and you can use the star form
+% without mandatory argument.
+%
+% Note, neither of the following commands are necessary for
+% \cs{ProcessKeyvalOptions{}}. They just help the package/class
+% author in common tasks.
+%
+% \subsubsection{\cs{SetupKeyvalOptions}}\label{setup}
+%
+% \begin{declcs}{SetupKeyvalOptions}\,\texttt{\{}\\
+%   \hspace{1.5em}|family|\,|=|\,\meta{family}|,|\\
+%   \hspace{1.5em}|prefix|\,|=|\,\meta{prefix}\\
+%   \texttt{\}}
+% \end{declcs}
+% This command allows to configure the default assumptions
+% that are based on the current package or class name.
+% \LaTeX\ remembers this name in \cs{@currname}. The syntax
+% description of the default looks a little weird, therefor
+% an example is given for a package or class named |foobar|.
+% \begin{quote}
+% \begin{tabular}{l|ll|l}
+%   Key & Default & (example) & Used by\\
+% \hline
+%   \rule{0pt}{1.2\ht\csname @arstrutbox\endcsname}^^A
+%   |family| & \meta{\cs{\@currname}} & (|foobar|)
+%       & \cs{ProcessKeyvalOptions*} \\
+%     &&& \cs{DeclareBooleanOption} \\
+%     &&& \cs{DeclareStringOption} \\
+% \hline
+%   \rule{0pt}{1.2\ht\csname @arstrutbox\endcsname}^^A
+%   |prefix| & \meta{\cs{\@currname}}|@| & (|foobar@|)
+%       & \cs{DeclareBooleanOption} \\
+%     &&& \cs{DeclareStringOption} \\
+%     &&& \cs{DeclareVoidOption}
+% \end{tabular}
+% \end{quote}
+%
+% \subsection{Option declarations}
+%
+% The options for \cs{ProcessKeyvalOptions} are defined
+% by \xpackage{keyval}'s \cs{define@key}.
+% Common purposes of such keys are boolean switches, they
+% enable or disable something. Or they store a name or some kind of
+% string in a macro. The following commands help the user. He
+% declares what he wants and \xpackage{kvoptions} take care of
+% the key definition, resource allocation and initialization.
+%
+% In order to avoid name clashes of macro names, internal
+% commands are prefixed. Both the prefix and the family
+% name for the defined keys can be configured by
+% \cs{SetupKeyvalOptions}.
+%
+% \subsubsection{\cs{DeclareStringOption}}
+%
+% \begin{declcs}{DeclareStringOption}\,\O{init}\,\M{key}\,\O{default}
+% \end{declcs}
+% A macro is created that remembers the value of the key \meta{key}.
+% The name of the macro consists of the option name \meta{key} that
+% is prefixed by the prefix (see \ref{setup}).
+% The initial contents of the
+% macro can be given by the first optional argument \meta{init}.
+% The default is empty.
+%
+% The the option \meta{key} is defined. The option code
+% just stores its value in the macro. If the optional argument
+% at the end of \cs{DeclareStringOption} is given, then option
+% \meta{key} is defined with the default \meta{default}.
+%
+% Example for a package with the following two lines:
+% \begin{quote}
+% |\ProvidedPackage{foobar}|\\
+% |\DeclareStringOption[me]{name}|
+% \end{quote}
+% Then \cs{DeclareStringOption} defines the macro with content |me|,
+% note \LaTeX\ complains if the name of the macro already exists:
+% \begin{quote}
+% |\newcommand*{\foobar@name}{me}|
+% \end{quote}
+% The option definition is similar to:
+% \begin{quote}
+% |\define@key{foobar}{name}{%|\\
+% |  \renewcommand*{\foobar@name}{#1}%|\\
+% |}|
+% \end{quote}
+%
+% \subsubsection{\cs{DeclareBooleanOption}}
+%
+% \begin{declcs}{DeclareBooleanOption}\,\O{init}\,\M{key}
+% \end{declcs}
+% A boolean switch is generated, initialized by value \meta{init}
+% and the corresponding key \meta{key} is defined. If the
+% initialization value is not given, |false| is used as default.
+%
+% The internal actions of \cs{DeclareBooleanOption} are shown below.
+% The example is given for a package author who has the following
+% two lines in his package/class:
+% \begin{quote}
+% |\ProvidesPackage{foobar}|\\
+% |\DeclareBooleanOption{verbose}|
+% \end{quote}
+% First a new switch is created:
+% \begin{quote}
+%   |\newif\iffoobar@verbose|
+% \end{quote}
+% and initialized:
+% \begin{quote}
+%   |\foobar@verbosefalse|
+% \end{quote}
+% Finally the key is defined:
+% \begin{quote}
+%   |\define@key{foobar}{verbose}[true]{|\dots|}|
+% \end{quote}
+% The option code configures the boolean option in the following way:
+% If the author specifies |true| or |false| then the switch is
+% turned on or off respectivly. Also the option can be given without
+% explicit value. Then the switch is enabled.
+% Other values are reported as errors.
+%
+% Now the switch is ready to use in the package/class, e.g.:
+% \begin{quote}
+%   |\iffoobar@verbose|\\
+%   \qquad\textit{\% print verbose message}\\
+%   |\else|\\
+%   \qquad\textit{\% be quiet}\\
+%   |\fi|
+% \end{quote}
+% Users of package \cs{ifthen} can use the switch as
+% boolean:
+% \begin{quote}
+%   |\boolean{foobar@verbose}|
+% \end{quote}
+%
+% \subsubsection{\cs{DeclareComplementaryOption}}
+%
+% \begin{declcs}{DeclareComplementaryOption}\,\M{key}\,\M{parent}
+% \end{declcs}
+% Sometimes contrasting names are used to characterize the
+% two states of a boolean switch, for example \xoption{final}
+% vs.\@ \xoption{final}. Both options behave like boolean
+% options but they do not need to different switches, they
+% should share one. \cs{DeclareComplementaryOption} allows this.
+% The option \meta{key} shares the switch of option \meta{parent}.
+% Example:
+% \begin{quote}
+%   |\DeclareBooleanOption{draft}|\\
+%   |\DeclareComplementaryOption{final}{draft}|
+% \end{quote}
+% Then |final| sets the switch of \xoption{draft} to |false|, and
+% |final=false| enables the \xoption{draft} switch.
+%
+% \subsubsection{\cs{DeclareVoidOption}}
+%
+% \begin{declcs}{DeclareVoidOption}\,\M{key}\,\M{code}
+% \end{declcs}
+% \cs{ProcessKeyvalOptions} can be extended to recognize
+% options that are declared in traditional way by \cs{DeclareOption}.
+% But in case of the error that the user specifies a value, then
+% this option would not recognized as key value option because
+% of \cs{DeclareOption} and not detected as traditional option
+% because of the value part. The user would get an unknown option
+% error, difficult to understand.
+%
+% \cs{DeclareVoidOption} solves
+% this problem. It defines the option \meta{key} as key value option.
+% If the user specifies a value, a warning is given and the
+% value is ignored.
+%
+% The code part \meta{code} is stored in a macro.
+% The name of the macro consists of the option name \meta{key} that
+% is prefixed by the prefix (see \ref{setup}).
+% If the option is set, the macro will be executed. During the
+% execution \cs{CurrentOption} is available with the current key name.
+%
+% \subsubsection{\cs{DeclareDefaultOption}}
+%
+% \begin{declcs}{DeclareDefaultOption}\,\M{code}
+% \end{declcs}
+% This command does not define a key, it is the equivalent
+% to \LaTeX's \cs{DeclareOption*}. It allows the specification
+% of a default action \meta{code} that is invoked if an unknown option
+% is found.
+% During the execution of \meta{code}
+% \cs{CurrentOption} contains the current option string.
+% Additionally \cs{CurrentOptionValue} contains the value part
+% if the option string is parsable as key value pair, otherwise
+% it is \cs{relax}. \cs{CurrentOptionKey} contains the key of
+% the key value pair, or the whole option string, if it misses
+% the equal sign.
+%
+% Inside packages typical default actions are to pass unknown
+% options to another package. Or an error message can be thrown
+% by \cs{@unknownoptionerror}. This is the original error
+% message that \LaTeX\ gives for unkown package options.
+% This error message is easier to understand for the user
+% as the error message from package \xpackage{keyval} that
+% is given otherwise.
+%
+% A Class ignores unknown options and puts them on the
+% unused option list. Let \LaTeX\ do the job and just
+% call \cs{OptionNotUsed}. Or the options can be passed to
+% another class that is later loaded.
+%
+% \subsubsection{Dynamic options}
+%
+% Options of \LaTeX's package/class system are cleared
+% in \cs{ProcessOptions}. They modify the static model
+% of a package. For example, depending on option \xoption{bookmarks}
+% package \xpackage{hyperref} loads differently.
+%
+% Options, however,
+% defined by \xpackage{keyval}'s \cs{define@key} remain
+% defined, if the options are processed by \cs{setkeys}.
+% Therefore these options can also be used to model
+% the dynamic behaviour of a package. For example, in
+% \xpackage{hyperref} the link colors can be changed
+% everywhere until the end in |\end{document}|.
+%
+% However package \xpackage{color} is necessary and it
+% cannot be loaded after |\begin{document}|. Option \xoption{colorlinks}
+% that loads \xpackage{color} should be active until |\begin{document}|
+% and die in some way if it is too late for loading packages.
+% With \cs{DisableKeyvalOption} the package/class author can
+% specify and configure the death of an option and controls
+% the life period of the option.
+%
+% \subsubsection{\cs{DisableKeyvalOption}}
+%
+% \begin{declcs}{DisableKeyvalOption}\,\O{options}\,\M{family}\,\M{key}
+%   \\[0.5ex]
+%   \meta{options}:\\
+%   \hspace{1.5em}^^A
+%   \begin{tabular}[t]{@{}l@{ \texttt{=} }l@{\qquad}>{default: }l@{}}
+%     |action| & |undef|, |warning|, |error|, or |ignore|
+%     & |undef|
+%     \\
+%     \multicolumn{1}{@{}l}{|global| or |local|} & & |global|
+%     \\
+%     |package| or |class| & \meta{name}
+%     \\
+%   \end{tabular}^^A
+% \end{declcs}
+% \cs{DisableKeyvalOption} can be called to mark the end when
+% the option \meta{key} is no longer useful. The behaviour of
+% an option after its death can be configured by \xoption{action}:
+% \begin{description}
+% \item[\texttt{undef}:] The option will be undefined,
+%   If it is called, \cs{setkeys} reports an error because
+%   of unknown key.
+% \item[\texttt{error} or \texttt{warning}:] Use of the
+%  option will cause an error or warning message.
+%  Also these actions require that exclusivly either the
+%  package or class name is given in options \xoption{package}
+%  or \xoption{class}.
+% \item[\texttt{ignore}:] The use of the option will silently
+%  be ignored.
+% \end{description}
+% The option's death can be limited to the end of the current
+% group, if option \xoption{local} is given. Default is
+% \xoption{global}.
+%
+% The package/class author can wish the end of the option
+% already during the package loading, then he will have
+% static behaviour. In case of dynamic options \cs{DisableKeyvalOptions}
+% can be executed everywhere, also outside the package. Therefore
+% the family name and the package/class name is usually unknown for
+% \cs{DisableKeyvalOptions}. Therefore the argument for the family
+% name is mandatory and for some actions the package/class name
+% must be provided.
+%
+% Usually a macro would configure the option death, Example:
+% \begin{quote}
+%\begin{verbatim}
+%\ProvidesPackage{foobar}
+%\DeclareBooleanOption{color}
+%\DeclareStringOption[red]{emphcolor}
+%\ProcessKeyvalOptions*
+%
+%\newcommand*{\foobar@DisableOption}[2]{%
+%  \DisableKeyvalueOption[
+%    action={#1},
+%    package=foobar
+%  ]{foobar}{#2}%
+%}
+%
+%\iffoobar@color
+%  \RequirePackage{color}
+%  \renewcommand*{\emph}[1]{\textcolor{\foobar@emphcolor}{#1}}
+%\else
+%  % Option emphcolor is not wrong, if we have color support.
+%  % otherwise the option has no effect, but we don't want to
+%  % remove it. Therefore action 'ignore' is the best choice:
+%  \foobar@DisableOption{ignore}{emphcolor}
+%\fi
+%% No we don't need the option 'color'.
+%\foobar@DisableOption{warning}{color}
+%
+%% With color support option 'emphcolor' will dynamically change
+%% the color of \emph statements.
+%\end{verbatim}
+% \end{quote}
+%
+% \subsection{Summary of internal macros}
+%
+% The \cs{Declare}\texttt{\dots Option} commands define
+% macros, additionally to the macros generated by the key definition.
+% These macros can be used by the package/class author.
+% The name of the macros starts with the prefix \meta{prefix}
+% that can be configured by \cs{SetupKeyvalOptions}.
+% \begin{quote}
+% \def\prefix{\cs{}\meta{prefix}\meta{key}}^^A
+% \def\Hline{^^A
+%   \hline
+%   \rule{0pt}{1.2\ht\csname @arstrutbox\endcsname}^^A
+% }^^A
+% \begin{tabular}{l|>{\ttfamily}l|l}
+%   Declare \meta{key} & \textrm{Defined macro} & Description\\
+% \Hline
+%   \cs{DeclareStringOption}
+%    & \prefix & holds the string\\
+% \Hline
+%   \cs{DeclareBooleanOption}
+%     & \cs{if}\meta{prefix}\meta{key}& boolean switch\\
+%   &\prefix false& disable switch\\
+%   &\prefix true& enable switch\\
+% \Hline
+%   \cs{DeclareComplementaryOption}
+%     & \prefix false& enable parent switch\\
+%     & \prefix true& disable parent switch\\
+% \Hline
+%   \cs{DeclareVoidOption}
+%   & \prefix & holds the action
+% \end{tabular}
+% \end{quote}
+%
+% \hypersetup{bookmarksopenlevel=1}
+%
+% \section{Example}
+%
+% The following example defined a package that serves some
+% private color management. A boolean option \xoption{print} enables
+% print mode without colors. An option \xoption{emph} redefines
+% \cs{emph} to print in the given color. And the driver
+% can be specified by option \xoption{driver}.
+%
+%    \begin{macrocode}
+%<*example>
+    % Package identification
+    % -----------------------
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{example-mycolorsetup}[2006/06/01 Managing my colors]
+
+\RequirePackage{ifpdf}
+\RequirePackage{kvoptions}
+
+    % Option declarations
+    % -------------------
+
+\SetupKeyvalOptions{
+  family=MCS,
+  prefix=MCS@
+}
+    % Use a shorter family name and prefix
+
+    % Option print
+\DeclareBooleanOption{print}
+    % is the same as
+    % \DeclareBooleanOption[false]{print}
+
+    % Option driver
+\ifpdf
+  \DeclareStringOption[pdftex]{driver}
+\else
+  \DeclareStringOption[dvips]{driver}
+\fi
+
+    % Alternative interface for driver options
+\DeclareVoidOption{dvips}{\SetupDriver}
+\DeclareVoidOption{dvipdfm}{\SetupDriver}
+\DeclareVoidOption{pdftex}{\SetupDriver}
+    % In \SetupDriver we take the current option \CurrentOption
+    % and pass it to the driver option.
+    % The \expandafter commands expand \CurrentOption at the
+    % time, when \SetupDriver is executed and \CurrentOption
+    % has the correct meaning.
+\newcommand*{\SetupDriver}{%
+  \expandafter\@SetupDriver\expandafter{\CurrentOption}%
+}
+\newcommand*{\@SetupDriver}[1]{%
+  \setkeys{MCS}{driver={#1}}%
+}
+
+    % Option emph
+    % An empty value means, we want to have no color for \emph.
+    % If the user specifies option emph without value, the red is used.
+\DeclareStringOption{emph}[red]
+    % is the same as
+    % \DeclareStringOption[]{emph}[red]
+
+    % Default option rule
+\DeclareDefaultOption{%
+  \ifx\CurrentOptionValue\relax
+    \PackageWarningNoLine{\@currname}{%
+      Unknown option `\CurrentOption'\MessageBreak
+      is passed to package `color'%
+    }%
+    % Pass the option to package color.
+    % Again it is better to expand \CurrentOption.
+    \expandafter\PassOptionsToPackage\expandafter{\CurrentOption}{color}%
+  \else
+    % Package color does not take options with values.
+    % We provide the standard LaTeX error.
+    \@unknownoptionerror
+  \fi
+}
+
+    % Process options
+    % ---------------
+\ProcessKeyvalOptions*
+
+    % Implementation depending on option values
+    % -----------------------------------------
+    % Code for print mode
+\ifMCS@print
+  \PassOptionsToPackage{monochrome}{color}
+    % tells package color to use black and white
+\fi
+
+\RequirePackage[\MCS@driver]{color}
+    % load package color with the correct driver
+
+    % \emph setup
+\ifx\MCS@emph\@empty
+    % \@empty is a predefined macro with empty contents.
+    % the option value of option emph is empty, thus
+    % we do not want a redefinition of \emph.
+\else
+  \renewcommand*{\emph}[1]{%
+    \textcolor{\MCS@emph}{#1}%
+  }
+\fi
+%</example>
+%    \end{macrocode}
+%
+% \section{Package options}
+%
+% The package \xpackage{kvoptions} knows two package options
+% \xoption{patch} and \xoption{debugshow}.
+% The options of package \xpackage{kvoptions} are intended
+% for authors, not for package/class writers. Inside a package
+% it is too late for option \xoption{patch} and \xoption{debugshow}
+% enables some messages that are perhaps useful for the debugging
+% phase. Also \LaTeX\ is unhappy if a package is loaded
+% later again with options that are previously not given.
+% Thus package and class authors, stay with |\RequirePackage{kvoptions}|
+% without options.
+%
+% \subsection{Option \xoption{patch}}
+%
+% \LaTeX's system of package/class options has some severe limitations
+% that especially affects the value part if options are used as
+% pair of key and value.
+% \begin{itemize}
+% \item Spaces are removed, regardless where:
+%   \begin{quote}
+%     |\documentclass[box=0 0 400 600]{article}|
+%   \end{quote}
+%   Now each package will see |box=00400600| as global option.
+% \item In the previous case also braces would not help:
+%   \begin{quote}
+%     |\documentclass[box={0 0 400 600}]{article}|
+%   \end{quote}
+%   The result is an error message:
+%   \begin{quote}
+%     |! LaTeX Error: Missing \begin{document}.|
+%   \end{quote}
+%   As local option, however, it works if the package
+%   knows about key value options (By using this package, for example).
+% \item The requirements on robustness are extremly high.
+%   \LaTeX\ expands the option. All that will not work as environment
+%   name will break also as option. Even a \cs{relax} will generate
+%   an error message:
+%   \begin{quote}
+%     |! Missing \endcsname inserted.|
+%   \end{quote}
+%   Of course, \LaTeX\ does not use its protecting mechanisms.
+%   On contrary \cs{protect} itself will cause errors.
+% \item The options are expanded. But perhaps the package will
+%   do that, because it has to setup some things before?
+%   Example \xpackage{hyperref}:
+%   \begin{quote}
+%     |\usepackage[pdfauthor=M\"uller]{hyperref}|
+%   \end{quote}
+%   Package \xpackage{hyperref} does not see |M\"uller| but
+%   its expansion and it does not like it, you get many warnings
+%   \begin{quote}
+%     |Token not allowed in a PDFDocEncoded string|
+%   \end{quote}
+%   And the title becomes: |Mu127uller|.
+%   Therefore such options must usually be given after package
+%   \xpackage{hyperref}
+%   is loaded:
+%   \begin{quote}
+%     |\usepackage{hyperref}|\\
+%     |\hypersetup{pdfauthor=Fran\c coise M\"uller}|
+%   \end{quote}
+%   As package option it will even break with |Fran\c coise|
+%   because of the cedilla |\c c|, it is not robust enough.
+% \end{itemize}
+% For users that do not want with this limitations the package
+% offers option \xoption{patch}. It patches \LaTeX's option system
+% and tries to teach it also to handle options that are given
+% as pairs of key and value and to prevent expansion.
+% It can already be used at the very beginning, before \cs{documentclass}:
+% \begin{quote}
+%   |\RequirePackage[patch]{kvoptions}|\\
+%   |\documentclass[pdfauthor=Fran\c coise M\"uller]{article}|\\
+%   |\usepackage{hyperref}|
+% \end{quote}
+% The latest time is before the package where you want to use
+% problematic values:
+% \begin{quote}
+%   |\usepackage[patch]{kvoptions}|\\
+%   |\usepackage[Fran\c coise M\"uller]{hyperref}|
+% \end{quote}
+% Some remarks:
+% \begin{itemize}
+% \item The patch and requires \eTeX, its \cs{unexpanded} feature
+%   is much to nice. It is possible to work around using token
+%   registers. But the code becomes longer, slower, more difficult
+%   to read and maintain. The package without option \xoption{patch}
+%   works and will work without \eTeX.
+% \item The code for the patch is quite long, there are many test
+%   cases. Thus the probability for bugs is probably not too small.
+% \end{itemize}
+%
+% \subsection{Option \xoption{debugshow}}
+%
+% The name of this option follows the convention of packages
+% \xpackage{multicol}, \xpackage{tabularx}, and \xpackage{tracefnt}.
+% Currently it prints the setting of boolean options, declared
+% by \cs{DeclareBooleanOption} in the \xfile{.log} file, if that
+% boolean option is used.
+% You can activate the option by
+% \begin{itemize}
+% \item |\PassOptionsToPackage{debugshow}{kvoptions}|\\
+%       Put this somewhere before package \xpackage{kvoptions} is
+%       loaded first, e.g. before \cs{documentclass}.
+% \item |\RequirePackage[debugshow]{kvoptions}|\\
+%       Before \cs{documentclass} even an author has to use
+%       \cs{RequirePackage}. \cs{usepackage} only works after
+%       \cs{documentclass}.
+% \end{itemize}
+% The preferred method is \cs{PassOptionsToPackage}, because
+% it does not force the package loading and does not disturb,
+% if the package is not loaded later at all.
+%
+% \section{Limitations}
+%
+% \subsection{Compatibility}
+% \subsubsection{Option \xoption{patch} vs. package \xpackage{xkvltxp}}
+%
+% Package \xpackage{xkvltxp} from the \xpackage{xkeyval} project
+% has the same goal as \xpackage{kvoptions}'s
+% option \xoption{patch} and patches \LaTeX's kernel commands.
+% Of course they cannot be used both. The user must decide, which
+% method he prefers. Package \xpackage{kvoptions} drops option
+% \xoption{patch} if it detects that \xpackage{xkvltxp} is
+% already loaded.
+%
+% However both \emph{packages} can be used together, example:
+% \begin{quote}
+% |\usepackage{xkvltxp}|\\
+% |\usepackage[...]{foobar} % |\texttt{\itshape foobar using kvoptions}
+% \end{quote}
+% The other way should work, too.
+%
+% Package \xpackage{kvoptions} tries to catch more situations
+% and to be more robust.
+% For example, during the comparison of options it normalizes
+% them by removing spaces around |=| and the value. Thus the
+% following is not reported as option clash:
+% \begin{quote}
+%\begin{verbatim}
+%\RequirePackage[patch]{kvoptions}
+%\documentclass{article}
+%
+%\usepackage[scaled=0.7]{helvet}
+%\usepackage[scaled = 0.7]{helvet}
+%
+%\begin{document}
+%\end{document}
+%\end{verbatim}
+% \end{quote}
+%
+% \subsection{Limitations}
+%
+% \subsubsection{Option comparisons}
+%
+% In some situations \LaTeX\ compares options, e.g. option clash check,
+% \cs{@ifpackagewith}, \cs{@ifclasswith}. Apart from catcode and
+% sanitizing problems of option \xoption{patch}, there is another problem.
+% \LaTeX\ does not know about the type and default values of
+% options in key value style. Thus an option clash is reported,
+% even if the key value has the same meaning:
+% \begin{quote}
+% |\usepackage[scaled]{helvet} %| \texttt{\textit{default is }.95}\\
+% |\usepackage[.95]{helvet}|\\
+% |\usepackage[0.95]{helvet}|\\
+% \end{quote}
+%
+% \subsubsection{Option list parsing with option \xoption{patch}}
+%
+% With option \xoption{patch} the range of possible values
+% in key value specifications is much large, for example
+% the comma can be used, if enclosed in curly braces.
+%
+% Other packages, especially the packages that uses their
+% own process option code can be surprised to find tokens
+% inside options that they do not expect and errors would
+% be the consequence. To avoid errors the options, especially
+% the unused option list is sanitized. That means the list
+% will only contain tokens with catcode 12 (other) and
+% perhaps spaces (catcode 10). This allows a safe parsing
+% for other packages. But a comma in the value part is
+% no longer protected by curly braces because they have lost
+% their special meaning. This is the price for compatibility.
+%
+% Example:
+% \begin{quote}
+% |\RequirePackage[patch]{kvoptions}|\\
+% |\documentclass[a={a,b,c},b]{article}|\\
+% |\begin{document}|\\
+% |\end{document}|
+% \end{quote}
+% Result:
+% \begin{quote}
+% |LaTeX Warning: Unused global option(s):|\\
+% |    [a={a,c},b].|
+% \end{quote}
+%
+% \StopEventually{
+% }
+%
+% \section{Implementation}
+%
+% \subsection{Preamble}
+% \paragraph{Package identification.}
+%    \begin{macrocode}
+%<*package>
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{kvoptions}
+  [2006/06/01 v2.2 Connects package keyval with LaTeX options (HO)]
+%    \end{macrocode}
+%
+% \paragraph{External resources.}
+%    The package extends the support for key value pairs of
+%    package \cs{keyval} to package options. Thus the package
+%    needs to be loaded anyway. and we use it for
+%    \cs{SetupKeyvalOptions}. AFAIK this does not disturb
+%    users of \xpackage{xkeyval}.
+%    \begin{macrocode}
+\RequirePackage{keyval}
+%    \end{macrocode}
+%
+% \paragraph{Options}
+%    Option \xoption{debugshow} enables additional lines of
+%    code that prints information into the \xfile{.log}
+%    file.
+%    \begin{macrocode}
+\begingroup
+  \edef\x{\endgroup
+    \noexpand\AtEndOfPackage{%
+      \catcode\@ne=\the\catcode\@ne\relax
+      \catcode\tw@=\the\catcode\tw@\relax
+    }%
+  }%
+\x
+\catcode\@ne=14 %
+\catcode\tw@=14 %
+\DeclareOption{debugshow}{\catcode\@ne=9 }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\DeclareOption{patch}{\catcode\tw@=9 }
+%    \end{macrocode}
+%
+%    Optionen auswerten:
+%    \begin{macrocode}
+\ProcessOptions\relax
+%    \end{macrocode}
+%
+% \subsection{Option declaration macros}
+%
+% \subsubsection{\cs{SetupKeyvalOptions}}
+%
+%    The family for the key value pairs can be setup once
+%    and is remembered later.
+%    The package name seems a reasonable default for the
+%    family key, if it is not set by the package author.
+%
+%    \begin{macro}{\KVO@family}
+%    We cannot store the family setting in one macro,
+%    because the package should be usable for many
+%    other packages, too. Thus we remember the family
+%    setting in a macro, whose name contains the
+%    package name with extension, a key in \LaTeX's
+%    class/package system.
+%    \begin{macrocode}
+\define@key{KVO}{family}{%
+  \expandafter\edef\csname KVO@family@\@currname.\@currext\endcsname{#1}%
+}
+\def\KVO@family{%
+  \@ifundefined{KVO@family@\@currname.\@currext}{%
+    \@currname
+  }{%
+    \csname KVO@family@\@currname.\@currext\endcsname
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{\KVO@prefix}
+%    The value settings of options, declared by \cs{DeclareBooleanOption}
+%    and \cs{DeclareStringOption} need to be saved in macros.
+%    in the first case this is a switch \cs{if}\meta{prefix}\meta{key},
+%    in the latter case a macro \cs{}\meta{prefix}\meta{key}.
+%    The prefix can be configured, by \xoption{prefix} that is declared
+%    here. The default is the package name with |@| appended.
+%    \begin{macrocode}
+\define@key{KVO}{prefix}{%
+  \expandafter\edef\csname KVO@prefix@\@currname.\@currext\endcsname{#1}%
+}
+\def\KVO@prefix{%
+  \@ifundefined{KVO@prefix@\@currname.\@currext}{%
+    \@currname @%
+  }{%
+    \csname KVO@prefix@\@currname.\@currext\endcsname
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{\SetupKeyvalOptions}
+%    The argument of \cs{SetupKeyvalOptions} expects a key value
+%    list, known keys are \xoption{family} and \xoption{prefix}.
+%    \begin{macrocode}
+\newcommand*{\SetupKeyvalOptions}{%
+  \setkeys{KVO}%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+% \subsubsection{\cs{DeclareBooleanOption}}
+%
+%    \begin{macro}{\DeclareBooleanOption}
+%    Usually options of boolean type can be given by the
+%    user without value and this means a setting to \emph{true}.
+%    We follow this convention here. Also it simplifies the
+%    user interface.
+%
+%    The switch is created and initialized with \emph{false}.
+%    The default setting can be overwritten by the optional
+%    argument.
+%
+%    \LaTeX's \cs{newif} does not check for already defined
+%    macros, therefore we add this check here to prevent
+%    the user from accidently redefining of \TeX's primitives
+%    and other macros.
+%    \begin{macrocode}
+\newcommand*{\DeclareBooleanOption}[2][false]{%
+  \KVO@ifdefinable{if\KVO@prefix#2}{%
+    \KVO@ifdefinable{\KVO@prefix#2true}{%
+      \KVO@ifdefinable{\KVO@prefix#2false}{%
+        \expandafter\newif\csname if\KVO@prefix#2\endcsname
+        \@ifundefined{\KVO@prefix#2#1}{%
+          \PackageWarning{kvoptions}{%
+            Initialization of option `#2' failed,\MessageBreak
+            cannot set boolean option to `#1',\MessageBreak
+            use `true' or `false', now using `false'%
+          }%
+        }{%
+          \csname\KVO@prefix#2#1\endcsname
+        }%
+        \begingroup
+          \edef\x{\endgroup
+            \noexpand\define@key{\KVO@family}{#2}[true]{%
+              \noexpand\KVO@boolkey{\@currname}%
+              \ifx\@currext\@clsextension
+                \noexpand\@clsextension
+              \else
+                \noexpand\@pkgextension
+              \fi
+              {\KVO@prefix}{#2}{####1}%
+            }%
+          }%
+        \x
+      }%
+    }%
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{\DeclareComplementaryOption}
+%    The first argument is the key name, the second the
+%    key that must be a boolean option with the same
+%    current family and prefix. A new switch is not
+%    created for the new key, we have already a switch.
+%    Instead we define switch setting commands to work
+%    on the parent switch.
+%    \begin{macrocode}
+\newcommand*{\DeclareComplementaryOption}[2]{%
+  \@ifundefined{if\KVO@prefix#2}{%
+    \PackageError{kvoptions}{%
+      Cannot generate option code for `#1',\MessageBreak
+      parent switch `#2' does not exist%
+    }{%
+      You are inside %
+      \ifx\@currext\@clsextension class\else package\fi\space
+      `\@currname.\@currext'.\MessageBreak
+      `\KVO@family' is used as familiy for the keyval options.\MessageBreak
+      `\KVO@prefix' serves as prefix for internal switch macros.\MessageBreak
+      \MessageBreak
+      \@ehc
+    }%
+  }{%
+    \KVO@ifdefinable{\KVO@prefix#1true}{%
+      \KVO@ifdefinable{\KVO@prefix#1false}{%
+        \expandafter\let\csname\KVO@prefix#1false\expandafter\endcsname
+          \csname\KVO@prefix#2true\endcsname
+        \expandafter\let\csname\KVO@prefix#1true\expandafter\endcsname
+          \csname\KVO@prefix#2false\endcsname
+%    \end{macrocode}
+%    The same code part as in \cs{DeclareBooleanOption} can
+%    now be used.
+%    \begin{macrocode}
+        \begingroup
+          \edef\x{\endgroup
+            \noexpand\define@key{\KVO@family}{#1}[true]{%
+              \noexpand\KVO@boolkey{\@currname}%
+              \ifx\@currext\@clsextension
+                \noexpand\@clsextension
+              \else
+                \noexpand\@pkgextension
+              \fi
+              {\KVO@prefix}{#1}{####1}%
+            }%
+          }%
+        \x
+      }%
+    }%
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{\KVO@ifdefinable}
+%    Generate the command token LaTeX's \cs{@ifdefinable} expects.
+%    \begin{macrocode}
+\def\KVO@ifdefinable#1{%
+  \expandafter\@ifdefinable\csname #1\endcsname
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{\KVO@boolkey}
+%    We check explicitly for |true| and |false| to prevent
+%    the user from accidently calling other macros.
+%    \begin{quote}
+%    \begin{tabular}{@{}ll@{}}
+%    |#1|& package/class name\\
+%    |#2|& |\@pkgextension|/|\@clsextension|\\
+%    |#3|& prefix \\
+%    |#4|& key name\\
+%    |#5|& new value
+%    \end{tabular}
+%    \end{quote}
+%    \begin{macrocode}
+\def\KVO@boolkey#1#2#3#4#5{%
+  \edef\KVO@param{#5}%
+  \@onelevel@sanitize\KVO@param
+  \ifx\KVO@param\KVO@true
+    \expandafter\@firstofone
+  \else
+    \ifx\KVO@param\KVO@false
+      \expandafter\expandafter\expandafter\@firstofone
+    \else
+      \ifx#2\@clsextension
+        \expandafter\ClassWarning
+      \else
+        \expandafter\PackageWarning
+      \fi
+      {#1}{%
+        Value `\KVO@param' is not supported by\MessageBreak
+        option `#4'%
+      }%
+      \expandafter\expandafter\expandafter\@gobble
+    \fi
+  \fi
+  {%
+    ^^A\ifx#2\@clsextension
+    ^^A  \expandafter\ClassInfo
+    ^^A\else
+    ^^A  \expandafter\PackageInfo
+    ^^A\fi
+    ^^A{#1}{[option] #4=\KVO@param}%
+    \csname#3#4\KVO@param\endcsname
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\KVO@true}
+%    \begin{macro}{\KVO@false}
+%    The macros \cs{KVO@true} and \cs{KVO@false} are used
+%    for string comparisons. After \cs{@onelevel@sanitize}
+%    we have only tokens with catcode 12 (other).
+%    \begin{macrocode}
+\def\KVO@true{true}
+\def\KVO@false{false}
+\@onelevel@sanitize\KVO@true
+\@onelevel@sanitize\KVO@false
+%    \end{macrocode}
+%    \end{macro}
+%    \end{macro}
+%
+% \subsubsection{\cs{DeclareStringOption}}
+%
+%    \begin{macro}{\DeclareStringOption}
+%    \begin{macrocode}
+\newcommand*{\DeclareStringOption}[2][]{%
+  \@ifnextchar[{%
+    \KVO@DeclareStringOption{#1}{#2}@%
+  }{%
+    \KVO@DeclareStringOption{#1}{#2}{}[]%
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\KVO@DeclareStringOption}
+%    \begin{macrocode}
+\def\KVO@DeclareStringOption#1#2#3[#4]{%
+  \KVO@ifdefinable{\KVO@prefix#2}{%
+    \@namedef{\KVO@prefix#2}{#1}%
+    \begingroup
+      \ifx\\#3\\%
+        \toks@{}%
+      \else
+        \toks@{[{#4}]}%
+      \fi
+      \edef\x{\endgroup
+        \noexpand\define@key{\KVO@family}{#2}\the\toks@{%
+          ^^A\begingroup
+          ^^A  \toks@{####1}%
+          ^^A  \ifx\@currext\@clsextension
+          ^^A    \noexpand\ClassInfo
+          ^^A  \else
+          ^^A    \noexpand\PackageInfo
+          ^^A  \fi
+          ^^A  {\@currname}{%
+          ^^A    [option] #2={\noexpand\the\toks@}%
+          ^^A  }%
+          ^^A\endgroup
+          \noexpand\def
+          \expandafter\noexpand\csname\KVO@prefix#2\endcsname{####1}%
+        }%
+      }%
+    \x
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+% \subsubsection{\cs{DeclareVoidOption}}
+%
+%    \begin{macro}{\DeclareVoidOption}
+%    \begin{macrocode}
+\newcommand*{\DeclareVoidOption}[1]{%
+  \begingroup
+    \let\next\@gobbletwo
+    \KVO@ifdefinable{\KVO@prefix#1}{%
+      \let\next\@firstofone
+    }%
+  \expandafter\endgroup
+  \next{%
+    \begingroup
+      \edef\x{\endgroup
+        \noexpand\define@key{\KVO@family}{#1}[\KVO@VOID@]{%
+          \noexpand\KVO@voidkey{\@currname}%
+          \ifx\@currext\@clsextension
+            \noexpand\@clsextension
+          \else
+            \noexpand\@pkgextension
+          \fi
+          {#1}%
+          {####1}%
+          \expandafter\noexpand\csname\KVO@prefix#1\endcsname
+        }%
+      }%
+    \x
+    \@namedef{\KVO@prefix#1}%
+  }%
+}
+\def\KVO@VOID@{@VOID@}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\KVO@voidkey}
+%    \begin{tabular}{@{}ll@{}}
+%    |#1|& package/class name\\
+%    |#2|& |\@pkgextension|/|\@clsextension|\\
+%    |#3|& key name\\
+%    |#4|& default (|@VOID@|)\\
+%    |#5|& macro with option code
+%    \end{tabular}
+%    \begin{macrocode}
+\def\KVO@voidkey#1#2#3#4{%
+  \def\CurrentOption{#3}%
+  \begingroup
+    \def\x{#4}%
+  \expandafter\endgroup
+  \ifx\x\KVO@VOID@
+  \else
+    \ifx#2\@clsextension
+      \expandafter\ClassWarning
+    \else
+      \expandafter\PackageWarning
+    \fi
+    {#1}{%
+      Unexpected value for option `#3'\MessageBreak
+      is ignored%
+    }%
+  \fi
+  ^^A\ifx#2\@clsextension
+  ^^A  \expandafter\ClassInfo
+  ^^A\else
+  ^^A  \expandafter\PackageInfo
+  ^^A\fi
+  ^^A{#1}{[option] #3}%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+% \subsubsection{\cs{DeclareDefaultOption}}
+%
+%    \begin{macro}{\DeclareDefaultOption}
+%    \begin{macrocode}
+\newcommand*{\DeclareDefaultOption}{%
+  \@namedef{KVO@default@\@currname.\@currext}%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+% \subsection{Dynamic options}
+%
+% \subsubsection{\cs{DisableKeyvalOption}}
+%
+%    \begin{macrocode}
+\SetupKeyvalOptions{%
+  family=KVOdyn,%
+  prefix=KVOdyn@%
+}
+\DeclareBooleanOption[true]{global}
+\DeclareComplementaryOption{local}{global}
+\DeclareStringOption[undef]{action}
+\let\KVOdyn@name\relax
+\let\KVOdyn@ext\@empty
+\define@key{KVOdyn}{class}{%
+  \def\KVOdyn@name{#1}%
+  \let\KVOdyn@ext\@clsextension
+}
+\define@key{KVOdyn}{package}{%
+  \def\KVOdyn@name{#1}%
+  \let\KVOdyn@ext\@pkgextension
+}
+\newcommand*{\DisableKeyvalOption}[3][]{%
+  \begingroup
+    \setkeys{KVOdyn}{#1}%
+    \def\x{\endgroup}%
+    \@ifundefined{KVO@action@\KVOdyn@action}{%
+      \PackageError{kvoptions}{%
+        Unknown disable action
+        `\expandafter\strip@prefix\meaning\KVOdyn@action'\MessageBreak
+        for option `#3' in keyval family '#2'%
+      }\@ehc
+    }{%
+      \csname KVO@action@\KVOdyn@action\endcsname{#2}{#3}%
+    }%
+  \x
+}
+\def\KVO@action@undef#1#2{%
+  \edef\x{\endgroup
+    \ifKVOdyn@global\global\fi
+    \let
+    \expandafter\noexpand\csname KV@#1@#2\endcsname
+    \relax
+    \ifKVOdyn@global\global\fi
+    \let
+    \expandafter\noexpand\csname KV@#1@#2@default\endcsname
+    \relax
+  }%
+  ^^A\PackageInfo{kvoptions}{%
+  ^^A  [option] key `#2' of family `#1'\MessageBreak
+  ^^A  is disabled (undef, \ifKVOdyn@global global\else local\fi)%
+  ^^A}%
+}
+\def\KVO@action@ignore#1#2{%
+  \edef\x{\endgroup
+    \ifKVOdyn@global\global\fi
+    \let
+    \expandafter\noexpand\csname KV@#1@#2\endcsname
+    \@gobble
+    \ifKVOdyn@global\global\fi
+    \let
+    \expandafter\noexpand\csname KV@#1@#2@default\endcsname
+    \@empty
+  }%
+  ^^A\PackageInfo{kvoptions}{%
+  ^^A  [option] key `#2' of family `#1'\MessageBreak
+  ^^A  is disabled (ignore, \ifKVOdyn@global global\else local\fi)%
+  ^^A}%
+}
+\def\KVO@action@error{%
+  \KVO@do@action{error}%
+}
+\def\KVO@action@warning{%
+  \KVO@do@action{warning}%
+}
+%    \end{macrocode}
+%    \begin{tabular}{@{}ll@{}}
+%    |#1|& |error| or |warning|\\
+%    |#2|& \meta{family}\\
+%    |#3|& \meta{key}\\
+%    \end{tabular}
+%    \begin{macrocode}
+\def\KVO@do@action#1#2#3{%
+  \ifx\KVOdyn@name\relax
+    \PackageError{kvoptions}{%
+      Action type `#1' needs package/class name\MessageBreak
+      for key `#3' in family `#2'%
+    }\@ehc
+  \else
+    \edef\x{\endgroup
+      \noexpand\define@key{#2}{#3}[]{%
+        \expandafter\noexpand\csname KVO@disable@#1\endcsname
+        {\KVOdyn@name}\noexpand\KVOdyn@ext{#3}%
+      }%
+      \ifKVOdyn@global
+        \global\let
+        \expandafter\noexpand\csname KV@#2@#3\endcsname
+        \expandafter\noexpand\csname KV@#2@#3\endcsname
+        \global\let
+        \expandafter\noexpand\csname KV@#2@#3@default\endcsname
+        \expandafter\noexpand\csname KV@#2@#3@default\endcsname
+      \fi
+    }%
+    ^^A\ifx\KVOdyn@ext\@clsextension
+    ^^A  \expandafter\ClassInfo
+    ^^A\else
+    ^^A   \expandafter\PackageInfo
+    ^^A\fi
+    ^^A{\KVOdyn@name}{%
+    ^^A  [option] key `#3' of family `#2'\MessageBreak
+    ^^A  is disabled (#1, \ifKVOdyn@global global\else local\fi)%
+    ^^A}%
+  \fi
+}
+\def\KVO@disable@error#1#2#3{%
+  \ifx#2\@clsextension
+    \expandafter\ClassError
+  \else
+    \expandafter\PackageError
+  \fi
+  {#1}{%
+    Option `#3' is given too late,\MessageBreak
+    now the option is ignored%
+  }\@ehc
+}
+\def\KVO@disable@warning#1#2#3{%
+  \ifx#2\@clsextension
+    \expandafter\ClassWarning
+  \else
+    \expandafter\PackageWarning
+  \fi
+  {#1}{%
+    Option `#3' is already consumed\MessageBreak
+    and has no effect%
+  }%
+}
+%    \end{macrocode}
+%
+% \subsection{Process options}
+%
+% \subsection{\cs{ProcessKeyvalOptions}}
+%
+%    \begin{macro}{\ProcessKeyvalOptions}
+%    If the optional star is given, we get the family
+%    name and expand it for safety.
+%    \begin{macrocode}
+\newcommand*{\ProcessKeyvalOptions}{%
+  \@ifstar{%
+    \begingroup
+      \edef\x{\endgroup
+        \noexpand\KVO@ProcessKeyvalOptions{\KVO@family}%
+      }%
+    \x
+  }%
+  \KVO@ProcessKeyvalOptions
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macrocode}
+\def\KVO@ProcessKeyvalOptions#1{%
+  \let\@tempc\relax
+  \let\KVO@temp\@empty
+%    \end{macrocode}
+%    Add any global options that are known to KV to the start of
+%    the list being built in |\KVO@temp| and mark them used (by
+%    removing them from the unused option list).
+%    \begin{macrocode}
+  \ifx\@currext\@clsextension
+  \else
+    \ifx\@classoptionslist\relax
+    \else
+      \@for\KVO@CurrentOption:=\@classoptionslist\do{%
+        \@ifundefined{KV@#1@\expandafter\KVO@getkey\KVO@CurrentOption=\@nil}{%
+        }{%
+          \edef\KVO@temp{%
+^^B         \unexpanded\expandafter{%
+              \KVO@temp
+^^B         }%
+            ,%
+^^B         \unexpanded\expandafter{%
+              \KVO@CurrentOption
+^^B         }%
+            ,%
+          }%
+^^B       \@onelevel@sanitize\KVO@CurrentOption
+          \@expandtwoargs\@removeelement\KVO@CurrentOption
+            \@unusedoptionlist\@unusedoptionlist
+        }%
+      }%
+    \fi
+  \fi
+%    \end{macrocode}
+%     Now stick the package options at the end of the list and wrap
+%     in a call to \cs{setkeys}. A class ignores unknown global
+%     options, we must remove them to prevent error messages
+%     from \cs{setkeys}.
+%    \begin{macrocode}
+  \begingroup
+    \toks\tw@{}%
+    \@ifundefined{opt@\@currname.\@currext}{%
+      \toks@\expandafter{\KVO@temp}%
+    }{%
+      \toks@\expandafter\expandafter\expandafter{%
+        \csname opt@\@currname.\@currext\endcsname
+      }%
+      \ifx\@currext\@clsextension
+        \edef\CurrentOption{\the\toks@}%
+        \toks@\expandafter{\KVO@temp}%
+        \@for\CurrentOption:=\CurrentOption\do{%
+          \@ifundefined{%
+            KV@#1@\expandafter\KVO@getkey\CurrentOption=\@nil
+          }{%
+%    \end{macrocode}
+%    A class puts not used options in the unused option list.
+%    \begin{macrocode}
+^^B         \@onelevel@sanitize\CurrentOption
+            \ifx\@unusedoptionlist\@empty
+              \global\let\@unusedoptionlist\CurrentOption
+            \else
+              \expandafter\expandafter\expandafter\gdef
+              \expandafter\expandafter\expandafter\@unusedoptionlist
+              \expandafter\expandafter\expandafter{%
+                \expandafter\@unusedoptionlist
+                \expandafter,\CurrentOption
+              }%
+            \fi
+          }{%
+            \toks@\expandafter{%
+              \the\expandafter\toks@\expandafter,\CurrentOption
+            }%
+          }%
+        }%
+      \else
+%    \end{macrocode}
+%    Without default action we pass all options to \cs{setkeys}.
+%    Otherwise we have to check which options are known.
+%    These are passed to \cs{setkeys}. For the others the default
+%    action is performed.
+%    \begin{macrocode}
+        \@ifundefined{KVO@default@\@currname.\@currext}{%
+          \toks@\expandafter\expandafter\expandafter{%
+            \expandafter\KVO@temp\the\toks@
+          }%
+        }{%
+          \edef\CurrentOption{\the\toks@}%
+          \toks@\expandafter{\KVO@temp}%
+          \@for\CurrentOption:=\CurrentOption\do{%
+            \@ifundefined{%
+              KV@#1@\expandafter\KVO@getkey\CurrentOption=\@nil
+            }{%
+              \toks\tw@\expandafter{%
+                \the\toks\expandafter\tw@\expandafter,\CurrentOption
+              }%
+            }{%
+              \toks@\expandafter{%
+                \the\expandafter\toks@\expandafter,\CurrentOption
+              }%
+            }%
+          }%
+        }%
+      \fi
+    }%
+    \edef\KVO@temp{\endgroup
+      \noexpand\KVO@calldefault{\the\toks\tw@}%
+      \noexpand\setkeys{#1}{\the\toks@}%
+    }%
+  \KVO@temp
+%    \end{macrocode}
+%    Some cleanup of \cs{ProcessOptions}.
+%    \begin{macrocode}
+  \let\CurrentOption\@empty
+  \AtEndOfPackage{\let\@unprocessedoptions\relax}%
+}
+%    \end{macrocode}
+%
+% \subsubsection{Helper macros}
+%
+%    \begin{macro}{\KVO@getkey}
+%    Extract the key part of a key=value pair.
+%    \begin{macrocode}
+\def\KVO@getkey#1=#2\@nil{#1}
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{\KVO@calldefault}
+%    \begin{macrocode}
+\def\KVO@calldefault#1{%
+  \begingroup
+    \def\x{#1}%
+  \expandafter\endgroup
+  \ifx\x\@empty
+  \else
+    \@for\CurrentOption:=#1\do{%
+      \ifx\CurrentOption\@empty
+      \else
+        \expandafter\KVO@setcurrents\CurrentOption=\@nil
+        \@nameuse{KVO@default@\@currname.\@currext}%
+      \fi
+    }%
+  \fi
+}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\KVO@setcurrents}
+%    Extract the key part of a key=value pair.
+%    \begin{macrocode}
+\def\KVO@setcurrents#1=#2\@nil{
+  \def\CurrentOptionValue{#2}%
+  \ifx\CurrentOptionValue\@empty
+    \let\CurrentOptionKey\CurrentOption
+    \let\CurrentOptionValue\relax
+  \else
+    \edef\CurrentOptionKey{\zap@space#1 \@empty}%
+    \expandafter\KVO@setcurrentvalue\CurrentOption\@nil
+  \fi
+}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\KV@setcurrentvalue}
+%    Here the value part is parsed. Package \xpackage{keyval}'s
+%    \cs{KV@@sp@def} helps in removing spaces at the begin and
+%    end of the value.
+%    \begin{macrocode}
+\def\KVO@setcurrentvalue#1=#2\@nil{%
+  \KV@@sp@def\CurrentOptionValue{#2}%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+% \subsection{Patch}
+%
+%    Caution: docstrip stops at \cs{endinput} at begin of line!
+%    \begin{macrocode}
+^^B\@gobble
+           \endinput
+\PackageInfo{kvoptions}{Patching LaTeX's option system}
+%    \end{macrocode}
+%
+%    Check for \eTeX.
+%    \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname eTeXversion\endcsname\relax
+  \PackageWarningNoLine{kvoptions}{%
+    Option `patch' ignored, because e-TeX is missing%
+  }%
+  \expandafter\endinput
+\fi
+%    \end{macrocode}
+%
+%    Check for package \xpackage{xkvltxp}.
+%    \begin{macrocode}
+\@ifpackageloaded{xkvltxp}{%
+  \PackageWarningNoLine{kvoptions}{%
+    Option `patch' cannot be used together with\MessageBreak
+    package `xkvltxp' that is already loaded.\MessageBreak
+    Therefore option `patch' will be ignored%
+  }%
+  \endinput
+}{}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\@if@ptions#1#2#3{%
+  \begingroup
+    \KVO@normalize\KVO@temp{#3}%
+    \edef\x{\endgroup
+      \noexpand\@if@pti@ns{%
+        \detokenize\expandafter\expandafter\expandafter{%
+          \csname opt@#2.#1\endcsname
+        }%
+      }{%
+        \detokenize\expandafter{\KVO@temp}%
+      }%
+    }%
+  \x
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\@pass@ptions#1#2#3{%
+  \KVO@normalize\KVO@temp{#2}%
+  \@ifundefined{opt@#3.#1}{%
+    \expandafter\gdef\csname opt@#3.#1%
+          \expandafter\endcsname\expandafter{%
+      \KVO@temp
+    }%
+  }{%
+    \expandafter\gdef\csname opt@#3.#1%
+          \expandafter\expandafter\expandafter\endcsname
+          \expandafter\expandafter\expandafter{%
+      \csname opt@#3.#1\expandafter\endcsname\expandafter,\KVO@temp
+    }%
+  }%
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\ProcessOptions{%
+  \let\ds@\@empty
+  \@ifundefined{opt@\@currname.\@currext}{%
+    \let\@curroptions\@empty
+  }{%
+    \expandafter\expandafter\expandafter\def
+    \expandafter\expandafter\expandafter\@curroptions
+    \expandafter\expandafter\expandafter{%
+      \csname opt@\@currname.\@currext\endcsname
+    }%
+  }%
+  \@ifstar\KVO@xprocess@ptions\KVO@process@ptions
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\KVO@process@ptions{%
+  \@for\CurrentOption:=\@declaredoptions\do{%
+    \ifx\CurrentOption\@empty
+    \else
+      \begingroup
+        \ifx\@currext\@clsextension
+          \toks@{}%
+        \else
+          \toks@\expandafter{\@classoptionslist,}%
+        \fi
+        \toks\tw@\expandafter{\@curroptions}%
+        \edef\x{\endgroup
+          \noexpand\in@{,\CurrentOption,}{,\the\toks@\the\toks\tw@,}%
+        }%
+      \x
+      \ifin@
+        \KVO@use@ption
+        \expandafter\let\csname ds@\CurrentOption\endcsname\@empty
+      \fi
+    \fi
+  }%
+  \KVO@process@pti@ns
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\KVO@xprocess@ptions{%
+  \ifx\@currext\@clsextension
+  \else
+    \@for\CurrentOption:=\@classoptionslist\do{%
+      \ifx\CurrentOption\@empty
+      \else
+        \KVO@in@\CurrentOption\@declaredoptions
+        \ifin@
+          \KVO@use@ption
+          \expandafter\let\csname ds@\CurrentOption\endcsname\@empty
+        \fi
+      \fi
+    }%
+  \fi
+  \KVO@process@pti@ns
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\KVO@in@#1#2{%
+  \in@false
+  \begingroup
+    \@for\x:=#2\do{%
+      \ifx\x#1\relax
+        \in@true
+      \fi
+    }%
+    \edef\x{\endgroup
+      \ifin@
+        \noexpand\in@true
+      \fi
+    }%
+  \x
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\KVO@process@pti@ns{%
+  \@for\CurrentOption:=\@curroptions\do{%
+    \@ifundefined{ds@\KVO@SanitizedCurrentOption}{%
+      \KVO@use@ption
+      \default@ds
+    }%
+    \KVO@use@ption
+  }%
+  \@for\CurrentOption:=\@declaredoptions\do{%
+    \expandafter\let\csname ds@\CurrentOption\endcsname\relax
+  }%
+  \let\CurrentOption\@empty
+  \let\@fileswith@pti@ns\@@fileswith@pti@ns
+  \AtEndOfPackage{\let\@unprocessedoptions\relax}%
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\KVO@use@ption{%
+  \begingroup
+    \edef\x{\endgroup
+      \noexpand\@removeelement{%
+        \detokenize\expandafter{\CurrentOption}%
+      }{%
+        \detokenize\expandafter{\@unusedoptionlist}%
+      }%
+    }%
+  \x\@unusedoptionlist
+  \csname ds@\KVO@SanitizedCurrentOption\endcsname
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\OptionNotUsed{%
+  \ifx\@currext\@clsextension
+    \xdef\@unusedoptionlist{%
+      \ifx\@unusedoptionlist\@empty
+      \else
+        \detokenize\expandafter{\@unusedoptionlist,}%
+      \fi
+      \detokenize\expandafter{\CurrentOption}%
+    }%
+  \fi
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\KVO@fileswith@pti@ns#1[#2]#3[#4]{%
+  \ifx#1\@clsextension
+    \ifx\@classoptionslist\relax
+      \KVO@normalize\KVO@temp{#2}%
+      \expandafter\gdef\expandafter\@classoptionslist\expandafter{%
+        \KVO@temp
+      }%
+      \def\reserved@a{%
+        \KVO@onefilewithoptions#3[#2][#4]#1%
+        \@documentclasshook
+      }%
+    \else
+      \def\reserved@a{%
+        \KVO@onefilewithoptions#3[#2][#4]#1%
+      }%
+    \fi
+  \else
+    \begingroup
+      \let\KVO@temp\relax
+      \let\KVO@onefilewithoptions\relax
+      \let\@pkgextension\relax
+      \def\reserved@b##1,{%
+        \ifx\@nil##1\relax
+        \else
+          \ifx\relax##1\relax
+          \else
+            \KVO@onefilewithoptions##1[\KVO@temp][#4]\@pkgextension
+          \fi
+          \expandafter\reserved@b
+        \fi
+      }%
+      \edef\reserved@a{\zap@space#3 \@empty}%
+      \edef\reserved@a{\expandafter\reserved@b\reserved@a,\@nil,}%
+      \toks@{#2}%
+      \def\KVO@temp{\the\toks@}%
+    \edef\reserved@a{\endgroup \reserved@a}%
+  \fi
+  \reserved@a
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\KVO@onefilewithoptions#1[#2][#3]#4{%
+  \@pushfilename
+  \xdef\@currname{#1}%
+  \global\let\@currext#4%
+  \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty
+  \let\CurrentOption\@empty
+  \@reset@ptions
+  \makeatletter
+  \def\reserved@a{%
+    \@ifl@aded\@currext{#1}{%
+      \@if@ptions\@currext{#1}{#2}{%
+      }{%
+        \begingroup
+          \@ifundefined{opt@#1.\@currext}{%
+            \def\x{}%
+          }{%
+            \edef\x{%
+              \expandafter\expandafter\expandafter\strip@prefix
+              \expandafter\meaning\csname opt@#1.\@currext\endcsname
+            }%
+          }%
+          \def\y{#2}%
+          \edef\y{\expandafter\strip@prefix\meaning\y}%
+          \@latex@error{Option clash for \@cls@pkg\space #1}{%
+            The package #1 has already been loaded
+            with options:\MessageBreak
+            \space\space[\x]\MessageBreak
+            There has now been an attempt to load it
+             with options\MessageBreak
+            \space\space[\y]\MessageBreak
+            Adding the global options:\MessageBreak
+            \space\space
+                 \x,\y\MessageBreak
+            to your \noexpand\documentclass declaration may fix this.%
+            \MessageBreak
+            Try typing \space <return> \space to proceed.%
+          }%
+        \endgroup
+      }%
+    }{%
+      \@pass@ptions\@currext{#2}{#1}%
+      \global\expandafter
+      \let\csname ver@\@currname.\@currext\endcsname\@empty
+      \InputIfFileExists
+        {\@currname.\@currext}%
+        {}%
+        {\@missingfileerror\@currname\@currext}%
+      \let\@unprocessedoptions\@@unprocessedoptions
+      \csname\@currname.\@currext-h@@k\endcsname
+      \expandafter\let\csname\@currname.\@currext-h@@k\endcsname
+              \@undefined
+      \@unprocessedoptions
+    }%
+    \@ifl@ter\@currext{#1}{#3}{%
+    }{%
+      \@latex@warning@no@line{%
+        You have requested,\on@line,
+        version\MessageBreak
+          #3' of \@cls@pkg\space #1,\MessageBreak
+        but only version\MessageBreak
+         `\csname ver@#1.\@currext\endcsname'\MessageBreak
+        is available
+      }%
+    }%
+    \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi
+    \@popfilename
+    \@reset@ptions
+  }%
+  \reserved@a
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\@unknownoptionerror{%
+  \@latex@error{%
+    Unknown option `\KVO@SanitizedCurrentOption' %
+    for \@cls@pkg\space`\@currname'%
+  }{%
+    The option `\KVO@SanitizedCurrentOption' was not declared in
+    \@cls@pkg\space`\@currname', perhaps you\MessageBreak
+    misspelled its name.
+    Try typing \space <return>
+    \space to proceed.%
+  }%
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\@@unprocessedoptions{%
+  \ifx\@currext\@pkgextension
+    \@ifundefined{opt@\@currname.\@currext}{%
+      \let\@curroptions\@empty
+    }{%
+      \expandafter\let\expandafter\@curroptions
+          \csname opt@\@currname.\@currext\endcsname
+    }%
+    \@for\CurrentOption:=\@curroptions\do{%
+        \ifx\CurrentOption\@empty\else\@unknownoptionerror\fi
+    }%
+  \fi
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\KVO@SanitizedCurrentOption{%
+  \expandafter\strip@prefix\meaning\CurrentOption
+}
+%    \end{macrocode}
+%
+%    Normalize option list.
+%    \begin{macrocode}
+\def\KVO@normalize#1#2{%
+  \let\KVO@result\@empty
+  \KVO@splitcomma#2,\@nil
+  \let#1\KVO@result
+}
+\def\KVO@splitcomma#1,#2\@nil{%
+  \KVO@ifempty{#1}{}{%
+    \KVO@checkkv#1=\@nil
+  }%
+  \KVO@ifempty{#2}{}{\KVO@splitcomma#2\@nil}%
+}
+\def\KVO@ifempty#1{%
+  \expandafter\ifx\expandafter\\\detokenize{#1}\\%
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi
+}
+\def\KVO@checkkv#1=#2\@nil{%
+  \KVO@ifempty{#2}{%
+    % option without value
+    \edef\KVO@x{\zap@space#1 \@empty}%
+    \ifx\KVO@x\@empty
+      % ignore empty option
+    \else
+      % append to list
+      \edef\KVO@result{%
+        \unexpanded\expandafter{\KVO@result},\KVO@x
+      }%
+    \fi
+  }{%
+    % #1: "key", #2: "value="
+    % add key part
+    \edef\KVO@result{%
+      \unexpanded\expandafter{\KVO@result},%
+      \zap@space#1 \@empty
+    }%
+    \futurelet\@let@token\KVO@checkfirsttok#2 \@nil| = \@nil|\KVO@nil
+  }%
+}
+\def\KVO@checkfirsttok{%
+  \ifx\@let@token\bgroup
+    % no space at start
+    \expandafter\KVO@removelastspace\expandafter=%
+    % "<value><spaceopt>= \@nil"
+  \else
+    \expandafter\KVO@checkfirstA
+  \fi
+}
+\def\KVO@checkfirstA#1 #2\@nil{%
+  \KVO@ifempty{#2}{%
+    \KVO@removelastspace=#1 \@nil
+  }{%
+    \KVO@ifempty{#1}{%
+      \KVO@removelastspace=#2\@nil
+    }{%
+      \KVO@removelastspace=#1 #2\@nil
+    }%
+  }%
+}
+\def\KVO@removelastspace#1 = \@nil|#2\KVO@nil{%
+  \KVO@ifempty{#2}{%
+    \edef\KVO@result{%
+      \unexpanded\expandafter{\KVO@result}%
+      \unexpanded\expandafter{\KVO@removegarbage#1\KVO@nil}%
+    }%
+  }{%
+    \edef\KVO@result{%
+      \unexpanded\expandafter{\KVO@result}%
+      \unexpanded{#1}%
+    }%
+  }%
+}
+\def\KVO@removegarbage#1= \@nil#2\KVO@nil{#1}%
+%    \end{macrocode}
+%
+%    Arguments |#1| and |#2| are macros.
+%    \begin{macrocode}
+\def\KVO@removeelement#1#2{%
+  \begingroup
+    \toks@={}%
+    \@for\x:=#2\do{%
+      \ifx\x\@empty
+      \else
+        \ifx\x#1\relax
+        \else
+          \edef\t{\the\toks@}%
+          \ifx\t\@empty
+          \else
+            \toks@\expandafter{\the\toks@,}%
+          \fi
+          \toks@\expandafter{\the\expandafter\toks@\x}%
+        \fi
+      \fi
+    }%
+    \edef\x{\endgroup
+      \def\noexpand#2{\the\toks@}%
+    }%
+  \x
+}
+%    \end{macrocode}
+%
+%
+%    \begin{macrocode}
+\let\@@fileswith@pti@ns\KVO@fileswith@pti@ns
+\ifx\@fileswith@pti@ns\@badrequireerror
+\else
+  \let\@fileswith@pti@ns\KVO@fileswith@pti@ns
+\fi
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%</package>
+%    \end{macrocode}
+% \section{Installation}
+%
+% \paragraph{CTAN.} This package is available on
+% CTAN\footnote{\url{ftp://ftp.ctan.org/tex-archive/}}:
+% \begin{description}
+% \item[\CTAN{macros/latex/contrib/oberdiek/kvoptions.dtx}] The source file.
+% \item[\CTAN{macros/latex/contrib/oberdiek/kvoptions.pdf}] Documentation.
+% \end{description}
+%
+% \paragraph{Unpacking.} The \xfile{.dtx} file is a self-extracting
+% \docstrip\ archive. The files are extracted by running the
+% \xfile{.dtx} through \plainTeX:
+% \begin{quote}
+%   \verb|tex kvoptions.dtx|
+% \end{quote}
+%
+% \paragraph{TDS.} Now the different files must be moved into
+% the different directories in your installation TDS tree
+% (also known as \xfile{texmf} tree):
+% \begin{quote}
+% \sbox0{^^A
+% \begin{tabular}{@{}>{\ttfamily}l@{$\quad\rightarrow\quad$}>{\ttfamily}l@{}}
+%   kvoptions.sty & tex/latex/oberdiek/kvoptions.sty\\
+%   kvoptions.pdf & doc/latex/oberdiek/kvoptions.pdf\\
+%   example-mycolorsetup.sty & doc/latex/oberdiek/example-mycolorsetup.sty\\
+%   kvoptions.dtx & source/latex/oberdiek/kvoptions.dtx\\
+% \end{tabular}^^A
+% }%
+% \ifdim\wd0>\linewidth
+%   \mbox{}\nobreak\hskip0pt minus\leftmargin
+%   \usebox0
+%   \nobreak\hskip0pt minus\rightmargin
+% \else
+%   \usebox0
+% \fi
+% \end{quote}
+% If you have a \xfile{docstrip.cfg} that configures and enables \docstrip's
+% TDS installing feature, then some files can already be in the right
+% place, see the documentation of \docstrip.
+%
+% \paragraph{Refresh file databases.} If your \TeX~distribution
+% (\teTeX, \mikTeX, \dots) rely on file databases, you must refresh
+% these. For example, \teTeX\ users run \verb|texhash| or
+% \verb|mktexlsr|.
+%
+% Now the installation is complete.
+%
+% \subsection{Some details for the interested}
+%
+% \paragraph{Attached source.}
+%
+% The PDF documentation on CTAN also includes the
+% \xfile{.dtx} source file. It can be extracted by
+% AcrobatReader 6 or higher. Another option is \textsf{pdftk},
+% e.g. unpack the file into the current directory:
+% \begin{quote}
+%   \verb|pdftk kvoptions.pdf unpack_files output .|
+% \end{quote}
+%
+% \paragraph{Unpacking with \LaTeX.}
+% The \xfile{.dtx} chooses its action depending on the format:
+% \begin{description}
+% \item[\plainTeX:] Run \docstrip\ and extract the files.
+% \item[\LaTeX:] Generate the documentation.
+% \end{description}
+% If you insist on using \LaTeX\ for \docstrip\ (really,
+% \docstrip\ does not need \LaTeX), then inform the autodetect routine
+% about your intension:
+% \begin{quote}
+%   \verb|latex \install=y\input{kvoptions.dtx}|
+% \end{quote}
+% Do not forget to quote the argument according to the demands
+% of your shell.
+%
+% \paragraph{Generating the documentation.}
+% You can use both the \xfile{.dtx} or the \xfile{.drv} to generate
+% the documentation. The process can be configured by the
+% configuration file \xfile{ltxdoc.cfg}. For instance, put this
+% line into this file, if you want to have A4 as paper format:
+% \begin{quote}
+%   \verb|\PassOptionsToClass{a4paper}{article}|
+% \end{quote}
+% An example follows how to generate the
+% documentation with pdf\LaTeX:
+% \begin{quote}
+%\begin{verbatim}
+%pdflatex kvoptions.dtx
+%makeindex -s gind.ist kvoptions.idx
+%pdflatex kvoptions.dtx
+%makeindex -s gind.ist kvoptions.idx
+%pdflatex kvoptions.dtx
+%\end{verbatim}
+% \end{quote}
+%
+% \newcommand*{\bibpackage}[4]{^^A
+%   \bibitem{#1}
+%   Package \xpackage{#1}, #2, #3.^^A
+%   \ifx\\#4\\\else#4\fi\par
+% }
+%
+% \begin{thebibliography}{99}
+% \bibpackage{ifthen}{David Carlisle}{2001/05/26}
+%   {\CTAN{macros/latex/base/ifthen.dtx}}
+% \bibpackage{helvet}{Sebastian Rahtz, Walter Schmidt}{2004/01/26}
+%   {\CTAN{macros/latex/required/psnfss/psfonts.dtx}}
+% \bibpackage{hyperref}{Sebastian Rahtz, Heiko Oberdiek}{2006/02/12}
+%   {\CTAN{macros/latex/contrib/hyperref/}}
+% \bibpackage{keyval}{David Carlisle}{1999/03/16}
+%   {\CTAN{macros/latex/required/graphics/keyval.dtx}}
+% \bibpackage{multicol}{Frank Mittelbach}{2004/02/14}
+%   {\CTAN{macros/latex/required/tools/multicol.dtx}}
+% \bibpackage{tabularx}{David Carlisle}{1999/01/07}
+%   {\CTAN{macros/latex/required/tools/tabularx.dtx}}
+% \bibpackage{tracefnt}{Frank Mittelbach, Rainer Sch\"opf}{1997/05/29}
+%   {\CTAN{macros/latex/base/ltfsstrc.dtx}}
+% \bibpackage{xkeyval}{Hendri Adriaens}{2005/05/07}
+%   {\CTAN{macros/latex/contrib/xkeyval/}}
+% \bibitem{clsguide}
+%   The \LaTeX3 Project, \textit{\LaTeXe\ for class and package writers},
+%   2003/12/09.
+%   \CTAN{macros/latex/doc/clsguide.pdf}
+%
+% \end{thebibliography}
+%
+% \begin{History}
+%   \begin{Version}{0000/00/00 v0.0}
+%   \item
+%     Probably David Carlisle's code in \xpackage{hyperref}
+%     was the start.
+%   \end{Version}
+%   \begin{Version}{2004/02/22 v1.0}
+%   \item
+%     The first version was never published. It also
+%     has offered a patch to get rid of \LaTeX's option
+%     expansion.
+%   \end{Version}
+%   \begin{Version}{2006/02/16 v2.0}
+%   \item
+%     Now the package is redesigned with an easier
+%     user interface.
+%   \item
+%     \cs{ProcessKeyvalOptions} remains the central service, inherited
+%     from \xpackage{hyperref}'s \cs{ProcessOptionsWithKV}.
+%     Now the use inside classes is also supported.
+%   \item
+%     Provides help macros for boolean and simple string options.
+%   \item
+%     Fixes for the patch of \LaTeX{}. The patch is only enabled,
+%     if the user requests it.
+%   \end{Version}
+%   \begin{Version}{2006/02/20 v2.1}
+%   \item
+%     Unused option list is sanitized to prevent problems
+%     with other packages that uses own processing methods
+%     for key value options. Disadvantage: the unused global
+%     option detection is weakened.
+%   \item
+%     New option type by \cs{DeclareVoidOption} for options without
+%     value.
+%   \item
+%     Default rule by \cs{DeclareDefaultOption}.
+%   \item
+%     Dynamic options: \cs{DisableKeyvalOption}.
+%   \end{Version}
+%   \begin{Version}{2006/06/01 v2.2}
+%   \item
+%     Fixes for option \xoption{patch}.
+%   \end{Version}
+% \end{History}
+%
+% \PrintIndex
+%
+% \Finale
+\endinput
-- 
cgit v1.2.3

