summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-11 23:59:07 +0000
committerKarl Berry <karl@freefriends.org>2006-01-11 23:59:07 +0000
commit932f1e9334f5617a090f721262fa30074d5e7374 (patch)
tree191552bd7389639373d3b65e066ea817327315fb /Master/texmf-dist/source
parent59aa2576ef260def2b412abb242644e53aa0d071 (diff)
trunk/Master/texmf-dist/source/latex/xkeyval
git-svn-id: svn://tug.org/texlive/trunk@594 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r--Master/texmf-dist/source/latex/xkeyval/xkeyval.dtx5605
1 files changed, 5605 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/xkeyval/xkeyval.dtx b/Master/texmf-dist/source/latex/xkeyval/xkeyval.dtx
new file mode 100644
index 00000000000..5febf8c8960
--- /dev/null
+++ b/Master/texmf-dist/source/latex/xkeyval/xkeyval.dtx
@@ -0,0 +1,5605 @@
+% \iffalse meta-comment
+%
+% xkeyval package by Hendri Adriaens.
+%
+% Extract package files and examples and create documentation:
+% latex xkeyval.dtx
+% latex xkeyval.dtx
+% bibtex xkeyval
+% makeindex -s gglo.ist -o xkeyval.gls xkeyval.glo
+% makeindex -s gind.ist -o xkeyval.ind xkeyval.idx
+% latex xkeyval.dtx
+% latex xkeyval.dtx
+%
+% To finish the installation you have to move the following
+% files into a directory searched by TeX:
+% xkeyval.tex
+% keyval.tex
+% xkvtxhdr.tex
+% pst-xkey.tex
+% Additional to these files, LaTeX should be able to locate
+% the following files:
+% xkeyval.sty
+% xkvview.sty
+% xkvltxp.sty
+% pst-xkey.sty
+%
+%% ---------------------------------------
+%% Copyright (C) 2004-2005 Hendri Adriaens
+%% ---------------------------------------
+%%
+%% 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 Hendri Adriaens.
+%%
+%% This work consists of the file xkeyval.dtx and derived files
+%% keyval.tex, xkvtxhdr.tex, xkeyval.sty, xkeyval.tex, xkvview.sty,
+%% xkvltxp.sty, pst-xkey.tex, pst-xkey.sty, xkveca.cls, xkvecb.cls,
+%% xkvesa.sty, xkvesb.sty, xkvesc.sty, xkvex1.tex, xkvex2.tex,
+%% xkvex3.tex and xkvex4.tex.
+%%
+%% The following files constitute the xkeyval bundle and must be
+%% distributed as a whole: readme, xkeyval.pdf, keyval.tex,
+%% pst-xkey.sty, pst-xkey.tex, xkeyval.sty, xkeyval.tex, xkvview.sty,
+%% xkvltxp.sty, xkvtxhdr.tex, pst-xkey.dtx and xkeyval.dtx.
+%%
+% \fi
+%
+% \iffalse
+%<*batchfile>
+\begingroup
+\input docstrip
+\keepsilent
+\preamble
+\endpreamble
+\askforoverwritefalse
+\generate{
+ \file{xkeyval.tex}{\from{xkeyval.dtx}{xkvtex}}
+ \file{xkeyval.sty}{\from{xkeyval.dtx}{xkvlatex}}
+ \file{xkvview.sty}{\from{xkeyval.dtx}{xkvview}}
+ \file{xkvltxp.sty}{\from{xkeyval.dtx}{xkvltxpatch}}
+ \file{keyval.tex}{\from{xkeyval.dtx}{xkvkeyval}}
+ \file{xkvtxhdr.tex}{\from{xkeyval.dtx}{xkvheader}}
+ \file{pst-xkey.tex}{\from{xkeyval.dtx}{pxktex}}
+ \file{pst-xkey.sty}{\from{xkeyval.dtx}{pxklatex}}
+ \file{xkvex1.tex}{\from{xkeyval.dtx}{xkvex1}}
+ \file{xkvex2.tex}{\from{xkeyval.dtx}{xkvex2}}
+ \file{xkvex3.tex}{\from{xkeyval.dtx}{xkvex3}}
+ \file{xkvex4.tex}{\from{xkeyval.dtx}{xkvex4}}
+ \file{xkveca.cls}{\from{xkeyval.dtx}{xkveca}}
+ \file{xkvecb.cls}{\from{xkeyval.dtx}{xkvecb}}
+ \file{xkvesa.sty}{\from{xkeyval.dtx}{xkvesa}}
+ \file{xkvesb.sty}{\from{xkeyval.dtx}{xkvesb}}
+ \file{xkvesc.sty}{\from{xkeyval.dtx}{xkvesc}}
+ \file{xkvpream.ble}{\from{xkeyval.dtx}{preamble}}
+ \file{xkeyval.bib}{\from{xkeyval.dtx}{bib}}
+}
+\endgroup
+%</batchfile>
+%<*driver>
+\documentclass[a4paper]{ltxdoc}
+\input{xkvpream.ble}
+\begin{document}
+\DocInput{xkeyval.dtx}
+\let\Section\section\def\section*#1{\Section*{#1}\addcontentsline{toc}{section}{#1}}
+\bibliographystyle{plain}
+\bibliography{xkeyval}
+\section*{Acknowledgements}
+The author is grateful to Josselin Noirel, Till Tantau, Herbert
+Vo\ss, Carsten Heinz and Heiko Oberdiek for help and suggestions. Thanks go to
+Donald Arseneau for contributing the robust |\@ifnextcharacter| macro and
+to Morten H\o gholm for contributing a fast for-loop macro. Special
+thanks go to Uwe Kern for his ideas for improving the functionality
+of this package, a lot of useful comments on the package and the
+documentation and for contributing the |\@selective@sanitize| macro.
+\PrintChangesX\PrintIndexX
+\end{document}
+%</driver>
+% \fi
+%
+% \changes{v1.0}{2004/04/29}{Initial release}
+% \changes{v1.2}{2004/05/08}{Change to \cs{DeclareOptionXf}; macro is
+% now replaced}
+% \changes{v1.3}{2004/05/09}{Revision of documentation}
+% \changes{v1.4}{2004/08/24}{Made package \TeX\ compatible}
+% \changes{v1.4}{2004/08/24}{Renamed macros to \pf{keyval} names}
+% \changes{v1.4}{2004/08/24}{Changed package options}
+% \changes{v1.5}{2004/09/27}{Corrected some minor bugs}
+% \changes{v1.5}{2004/09/27}{Added \pf{pst-xkey}}
+% \changes{v1.5}{2004/09/27}{Revised documentation}
+% \changes{v1.5}{2004/09/27}{Added \cs{XKV@for}}
+% \changes{v1.6}{2004/10/05}{Changed loading preventions}
+% \changes{v1.6}{2004/10/05}{Corrected typos}
+% \changes{v1.7}{2004/11/25}{Improved coding}
+% \changes{v1.7}{2004/11/25}{Package uses \eTeX\ if available}
+% \changes{v1.7}{2004/11/25}{Changed \LaTeX\ patch from \texttt{.tex}
+% to \texttt{.sty}}
+% \changes{v1.7}{2004/11/25}{Updated license information}
+% \changes{v1.7}{2004/11/25}{Added system to control the scope of
+% definitions to various macros}
+% \changes{v1.8 }{2004/12/13}{Made package robust for catcode changes
+% of equality character}
+% \changes{v1.8 }{2004/12/13}{Fixed inconsistency of treatment of
+% spaces in key and family names, all left untouched now}
+% \changes{v1.8c}{2005/01/01}{Simplified and improved some code}
+% \changes{v1.8d}{2005/01/02}{Restructured package to indicate general
+% tools and their implementation}
+% \changes{v1.8d}{2005/01/02}{Renamed \texttt{xkeyval.def} to
+% \texttt{xkvtxhdr.tex}}
+% \changes{v1.9}{2005/01/16}{Added \cs{delpresetkeys}}
+% \changes{v1.9}{2005/01/16}{Added \cs{delsavekeys}}
+% \changes{v1.9}{2005/01/16}{Updated license information}
+% \changes{v2.0}{2005/01/30}{Made \cs{setkeys} nestable}
+% \changes{v2.1}{2005/02/08}{Added `immediate' versions of several
+% macros}
+% \changes{v2.2}{2005/02/14}{Improved nesting mechanism}
+% \changes{v2.2}{2005/02/14}{Added viewer utility}
+% \changes{v2.3}{2005/02/22}{Updated viewer utility}
+% \changes{v2.3}{2005/02/22}{Added choice keys}
+% \changes{v2.3}{2005/02/22}{Increased efficiency of loops}
+% \changes{v2.4}{2005/03/31}{Added nesting protection for conditionals}
+% \changes{v2.4}{2005/03/31}{Changed \cs{define@boolkey} to have a key
+% function}
+% \changes{v2.4}{2005/03/31}{Extended boolean keys}
+% \changes{v2.4}{2005/03/31}{Extended choice keys}
+% \changes{v2.4}{2005/03/31}{Updated \pf{xkvview}}
+% \changes{v2.4}{2005/03/31}{Added `default value' column to
+% \pf{xkvview} tables}
+% \changes{v2.4}{2005/03/31}{Revised documentation and examples}
+% \changes{v2.4}{2005/03/31}{Removed command keys}
+% \changes{v2.4}{2005/03/31}{Simplified some code}
+% \changes{v2.4}{2005/03/31}{Inserted \pf{pst-xkey} in \pf{xkeyval}
+% source}
+% \changes{v2.5 }{2005/05/07}{Added \cs{define@boolkeys},
+% \cs{define@cmdkey} and \cs{define@cmdkeys}}
+% \changes{v2.5 }{2005/05/07}{Restructured documentation}
+% \changes{v2.5 }{2005/05/07}{Updated \pf{xkvview}}
+% \changes{v2.5 }{2005/05/07}{Solved small bug in \cs{setkeys} which
+% allowed other families to take over save key or preset key settings
+% if the key was defined in multiple families}
+% \changes{v2.5 }{2005/05/07}{Simplified \cs{setkeys} internals}
+% \changes{v2.5 }{2005/05/21}{Reimplemented \pf{xkvview} and added
+% several options}
+% \changes{v2.5 }{2005/05/21}{Added default value examples to docs}
+% \changes{v2.5b}{2005/06/20}{Made retrieving document class more robust}
+% \changes{v2.5d}{2005/08/12}{Added missing \cs{filename@area} in
+% document class retrieval in \texttt{xkeyval.sty}}
+%
+% \GetFileInfo{xkeyval.sty}
+%
+% \CheckSum{2963}
+%
+%\DoNotIndex{\:,\@,\@@,\@backslashchar,\@ehc,\@empty,\@expandtwoargs,
+%\@for,\@forloop,\@fornoop,\@fortmp,\@gobble,\@gobbletwo,\@if,\@ifnch,
+%\@ifnextchar,\@iforloop,\@ifundefined,\@let@token,
+%\@namedef,\@nil,\@nnil,\@sptoken,\@temptokena,\@testopt,\@undefined,
+%\@xifnch,\\,\afterassignment,\AtEndOfPackage,\begingroup,\bgroup,
+%\catcode,\count@,\csname,\def,\do,\edef,\else,\endcsname,\endgroup,
+%\endinput,\errmessage,\escapechar,\eTeXversion,\expandafter,\fi,
+%\futurelet,\gdef,\global,\if,\ifcsname,\iffalse,\ifin@,\iftrue,\ifx,
+%\in@,\in@@,\in@false,\in@true,\input,\kernel@ifnextchar,\let,\long,
+%\lowercase,\m@ne,\meaning,\message,\NeedsTeXFormat,\newif,\newtoks,
+%\noexpand,\protect,\ProvidesFile,\ProvidesPackage,\relax,\reserved@a,
+%\reserved@b,\reserved@c,\reserved@d,\space,\string,\strip@prefix,\the,
+%\toks@,\xdef,\XKV@header,\XKV@inpoxfalse,\XKV@inpoxtrue,\XKV@knffalse,
+%\XKV@knftrue,\XKV@plfalse,\XKV@pltrue,\XKV@resa,\XKV@rkvfalse,
+%\XKV@rkvtrue,\XKV@stfalse,\XKV@sttrue,\XKV@tempa,\XKV@tempb,\XKV@tempc,
+%\XKV@tempd,\XKV@tfam,\XKV@tkey,\XKV@toks,\XKVcatcodes,\XKV@sgtrue,
+%\zap@space,\@@cmd,\@@tok,\@i,\@ii,\@iii,\@iv,\=,\XKV@rgtrue,\XKV@rgfalse,
+%\z@,\@ne,\m@ne,\count@,\advance,\ifnum,\,,\@M,\XKV@resb,\XKV@sgfalse,
+%\newcount,\ttfamily,\textst,\texttt,\ifcase,\begin,\bfseries,\end,
+%\hline,\multicolumn,\normalfont,\romannumeral,\emph,\endfirsthead,
+%\endfoot,\endhead,\endlastfoot,\textsf,\addto@hook,\RequirePackage,
+%\ifcat,\PSTXKeyCatcodes,\@addtofilelist,\XKV@presettrue,\XKV@presetfalse,
+%\protected@edef,\closeout,\openout,\label,\newwrite,\protected@write,
+%\XKVV@coliitrue,\XKVV@coliiitrue,\XKVV@colivtrue,\XKVV@colvtrue,
+%\XKVV@coliifalse,\XKVV@coliiifalse,\XKVV@colivfalse,\XKVV@colvfalse,
+%\XKVV@vwkeyfalse,\XKVV@vwkeytrue}
+%
+% \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 \~}
+%
+%\title{\vspace*{-1cm}The \pf{xkeyval} package
+%\thanks{This package can be downloaded from the CTAN mirrors:
+%\texttt{/macros/latex/contrib/xkeyval}. See \texttt{xkeyval.dtx} for
+%information on installing \pf{xkeyval} into your \TeX\ or \LaTeX\
+%distribution and for the license of this package.}}
+%\author{\mktitledecor Hendri Adriaens\\\url{http://stuwww.uvt.nl/~hendri}}
+%\date{\fileversion\ (\filedate)}
+%\maketitle
+%
+%\begin{abstract}\noindent
+%This package is an extension of the \pf{keyval} package and offers
+%more flexible macros for defining and setting keys. The package
+%provides a pointer and a preset system. Furthermore, it supplies
+%macros to allow class and package options to contain options of the
+%|key=value| form. A \LaTeX\ kernel patch is provided to avoid
+%premature expansions of macros in class or package options. A
+%specialized system for setting \pf{PSTricks} keys is provided by
+%the \pf{pst-xkey} package.
+%\end{abstract}
+%
+%\begin{multicols}{2}
+%[\section*{Contents}
+%\setlength{\columnseprule}{.4pt}
+%\setlength{\columnsep}{18pt}]
+%\tableofcontents
+%\end{multicols}
+%
+%\newpage
+%\section{Introduction}\label{sec:intro}
+%This package is an extension of the \pf{keyval} package by David Carlisle
+%\cite{keyval} and offers more flexible and robust macros for defining and
+%setting keys. Using keys in macro definition has the advantage that
+%the 9 arguments maximum can easily be avoided and that it reduces
+%confusion in the syntax of your macro when compared to using a lot
+%of (optional) arguments. Compare for instance the following
+%possible syntaxes of the macro |\mybox| which might for instance
+%use its arguments to draw some box containing text.
+%\begin{example}
+% \mybox[5pt][20pt]{some text}[red][white][blue]
+% \mybox[text=red,background=white,frame=blue,left=5pt,right=20pt]{some text}
+%\end{example}
+%Notice that, to be able to specify the frame color in the first
+%example, the other colors need to be specified as well. This is not
+%necessary in the second example and these colors can get preset
+%values. The same thing holds for the margins.
+%
+%The idea is that one first defines a set of keys using the tools
+%presented in section~\ref{sec:define} in the document preamble or in a
+%package or class. These keys can perform a function with the user
+%input. The way to submit user input to these key macros, is by using
+%one of the user interfaces described in sections~\ref{sec:setkeys},
+%\ref{sec:pointers} and~\ref{sec:preset}. The main user interface is
+%provided by the |\setkeys| command. Using these interfaces, one can
+%simplify macro syntax and for instance define the |\mybox| macro
+%above as follows.
+%\begin{example}
+% \define@key{mybox}{left}{\setlength\myleft{#1}}
+% \define@key{mybox}{background}{\def\background{#1}}
+% % and some other keys
+% \def\mybox{\@ifnextchar[\@mybox{\@mybox[]}}
+% \def\@mybox[#1]#2{%
+% \setkeys{mybox}{#1}%
+% % some operations to typeset #2
+% }
+%\end{example}
+%Notice that the combination of the two definitions |\mybox| and
+%|\@mybox| can be replaced by |\newcommand\mybox[2][]{...}|
+%when using \LaTeX.
+%
+%Both keys defined using the \pf{keyval} and \pf{xkeyval} can be set
+%by this package. The \pf{xkeyval} macros allow for scanning multiple
+%sets (called `families') of keys. This can, for instance, be used to
+%create local families for macros and environments which may not
+%access keys meant for other macros and environments, while at the
+%same time, allowing the use of a single command to (pre)set all of
+%the keys from the different families globally.
+%
+%The package is compatible to plain \TeX\ and redefines several
+%\pf{keyval} macros to provide an easy way to switch between using
+%\pf{keyval} and \pf{xkeyval}. This might be useful for package
+%writers that cannot yet rely on the availability of \pf{xkeyval} in
+%a certain distribution. After loading \pf{xkeyval}, loading
+%\pf{keyval} is prevented to make sure that the extended macros of
+%\pf{xkeyval} will not be redefined. Some internal \pf{keyval} macros
+%are supplied in |keyval.tex| to guarantee compatibility to packages
+%that use those macros. Section~\ref{sec:issues} provides more
+%information about this issue.
+%
+%The organization of this documentation is as follows.
+%Section~\ref{sec:loading} discusses how to load \pf{xkeyval} and
+%what the package does when it is loaded. Section~\ref{sec:define}
+%will discuss the macros available to define and manage keys.
+%Section~\ref{sec:setkeys} will continue with describing the macros
+%that can set the keys. Section~\ref{sec:pointers} explains special
+%syntax which will allow saving and copying key values. In
+%section~\ref{sec:preset}, the preset system will be introduced.
+%Section~\ref{sec:catcodes} will explain how \pf{xkeyval} protects
+%itself for catcode changes of the comma and the equality sign by
+%other packages. The \pf{xkeyval} package also provides commands to
+%declare and process class and package options that can take values.
+%These will be discussed in section~\ref{sec:options}.
+%Section~\ref{sec:macrostructs} provides an overview of structures
+%used to create \pf{xkeyval} internal macros used for keys, values,
+%presets, etcetera. Sections~\ref{sec:errors} and~\ref{sec:issues}
+%discuss feedback that \pf{xkeyval} might give and known issues,
+%respectively. Section~\ref{sec:additional} discusses several
+%additional packages that come with the \pf{xkeyval} bundle.
+%Section~\ref{sec:view} presents a viewer utility which produces
+%overviews of defined keys. An extension of the \LaTeXe\ kernel with
+%respect to the class and package options system is discussed in
+%section~\ref{sec:macrooptions}. This extension provides a way to use
+%expandable macros in package options. Section~\ref{sec:pst-xkey}
+%presents the \pf{pst-xkey} package, which provides an options system
+%based on \pf{xkeyval}, but which is specialized in setting
+%\pf{PSTricks} keys.
+%
+%Throughout this documentation, you will find some examples with a
+%short description. More examples can be found in the example files
+%that come with this package. See section~\ref{sec:sande} for more
+%information. This section also provides the information how to
+%generate the full documentation from the source.
+%
+%\section{Loading \pf{xkeyval}}\label{sec:loading}
+%To load the \pf{xkeyval} package,\footnote{The \pf{xkeyval} package
+%consists of the files \texttt{xkeyval.tex}, \texttt{xkeyval.sty},
+%\texttt{keyval.tex}, \texttt{xkvtxhdr.tex}.} plain \TeX\ users do
+%|\input xkeyval|. \LaTeX\ users do one of the following:
+%|\usepackage{xkeyval}| or |\RequirePackage{xkeyval}|. The package
+%does not have options. It is mandatory for \LaTeX\ users to load
+%\pf{xkeyval} at any point after the |\documentclass| command.
+%Loading \pf{xkeyval} from the class which is the document class
+%itself is possible. The package will use the \eTeX\ engine when
+%available. In particular, |\ifcsname| is used whenever possible to
+%avoid filling \TeX's hash tables with useless entries, for instance
+%when searching for keys in families.
+%
+%If \pf{xkeyval} is loaded by |\RequirePackage| or |\usepackage|, the
+%package performs two action immediately. These require
+%\pf{xkeyval} to be loaded at any point after |\documentclass| or by
+%the document class itself.
+%
+%First, it retrieves the document class of the document at hand and
+%stores that (including the class extension) into the following macro.
+%\begin{command}
+% `\cs{XKV@documentclass}'
+%\end{command}
+%\DescribeMacro{\XKV@documentclass}
+%This macro could, for instance, contain |article.cls| and can be useful
+%when using |\ProcessOptionsX*| in a class. See
+%page~\pageref{macro:poxstar}.
+%
+%Secondly, the global options submitted to the |\documentclass| command
+%and stored by \LaTeX\ in |\@classoptionslist|
+%are copied to the following macro.
+%\begin{command}
+% `\cs{XKV@classoptionslist}'
+%\end{command}
+%\DescribeMacro{\XKV@classoptionslist}
+%This macro will be used by |\ProcessOptionsX|. Options containing
+%an equality sign are deleted from the original list in
+%|\@classoptionslist| to avoid packages, which do not use \pf{xkeyval}
+%and which are loaded later, running into problems when trying to copy
+%global options using \LaTeX's |\ProcessOptions|.
+%
+%\section{Defining and managing keys}\label{sec:define}
+%\changes{v1.4}{2004/08/24}{Added prefix options to macros}
+%\changes{v1.7}{2004/11/25}{Removed optional key checking from define macros}
+%This section discusses macros to define keys and some tools to manage
+%keys. A useful extension to \pf{xkeyval} is the \pf{xkvview} package.
+%This packages defines commands to generate overviews of defined keys.
+%See section~\ref{sec:view} for more information.
+%
+%\subsection{Ordinary keys}\label{sec:odefine}
+%This section describes how to define ordinary keys.
+%\begin{command}
+% `\cs{define@key}\oarg{prefix}\marg{family}\marg{key}\oarg{default}\marg{function}'
+%\end{command}
+%\DescribeMacro{\define@key}
+%This defines a macro of the form
+%|\|\meta{prefix}|@|\meta{family}|@|\meta{key} with one argument
+%holding \meta{function}. The default value for \meta{prefix} is
+%|KV|. This is the standard throughout the package to simplify mixing
+%\pf{keyval} and \pf{xkeyval} keys. When \meta{key} is used in a
+%|\setkeys| command (see section~\ref{sec:setkeys}) containing
+%|key=value|, the macro |\|\meta{prefix}|@|\meta{family}|@|\meta{key}
+%receives |value| as its argument and will be executed. The argument
+%can be accessed by \meta{function} by using |#1| inside the
+%function.
+%\begin{example}
+% \define@key{family}{key}{The input is: #1}
+%\end{example}
+%\pf{xkeyval} will generate an error when the user omits |=value| for
+%a key in the options list of |\setkeys| (see
+%section~\ref{sec:setkeys}). To avoid this, the optional argument can
+%be used to specify a default value.
+%\begin{example}
+% \define@key{family}{key}[none]{The input is: #1}
+%\end{example}
+%This will additionally define a macro
+%|\|\meta{prefix}|@|\meta{family}|@|\meta{key}|@default| as a macro
+%with no arguments and definition
+%|\|\meta{prefix}|@|\meta{family}|@|\meta{key}|{none}| which will be
+%used when |=value| is missing for |key| in the options list. So, the
+%last example comes down to doing
+%\begin{example}
+% \def\KV@family@key#1{The input is: #1}
+% \def\KV@family@key@default{\KV@family@key{none}}
+%\end{example}
+%
+%When \meta{prefix} is specified and empty, the macros created by
+%|\define@key| will have the form |\|\meta{family}|@|\meta{key}. When
+%\meta{family} is empty, the resulting form will be
+%|\|\meta{prefix}|@|\meta{key}. When both \meta{prefix} and
+%\meta{family} are empty, the form is |\|\meta{key}. This combination
+%of prefix and family will be called the header. The rules to create
+%the header will be applied to all commands taking (optional) prefix
+%and family arguments.
+%
+%The intended use for \meta{family} is to create distinct sets of
+%keys. This can be used to avoid a macro setting keys meant for
+%another macro only. The optional \meta{prefix} can be used to
+%identify keys specifically for your package. Using a package
+%specific prefix reduces the probability of multiple packages
+%defining the same key macros. This optional argument can also be
+%used to set keys of some existing packages which use a system based
+%on \pf{keyval}.\footnote{Like \pf{PSTricks}, which uses a system
+%originating from \pf{keyval}, but which has been modified to use no
+%families and |psset| as prefix.}\label{page:pstricks}
+%
+%We now define some keys to be used in examples throughout this
+%documentation.
+%\begin{example}
+% \define@key[my]{familya}{keya}[default]{#1}
+% \define@key[my]{familya}{keyb}{#1}
+% \define@key[my]{familyb}{keyb}{#1}
+% \define@key[my]{familya}{keyc}{#1}
+%\end{example}
+%
+%\subsection{Command keys}\label{sec:cdefine}
+%Command keys are specialized keys that, before executing any code,
+%save the user input to a macro.
+%\begin{command}
+% `\cs{define@cmdkey}\oarg{prefix}\marg{family}\oarg{mp}\marg{key}\oarg{default}\marg{function}'
+%\end{command}
+%\DescribeMacro{\define@cmdkey}
+%This has the effect of defining a key macro of the form
+%|\|\meta{prefix}|@|\meta{family}|@|\meta{key} that, when used, first
+%saves the user input to a macro of the form |\|\meta{mp}\meta{key}
+%and then executes \meta{function}. \meta{mp} is the macro prefix. If
+%\meta{mp} is not specified, the usual combination of \meta{prefix}
+%and \meta{family}, together with the extra prefix |cmd|, will be
+%used to create the macro prefix, namely
+%|\cmd|\meta{prefix}|@|\meta{family}|@|.\footnote{\label{foot:1}Remember
+%that some rules are applied when creating the header, the
+%combination of \meta{prefix} and \meta{header}. See
+%section~\ref{sec:odefine}.} The two keys in the following example
+%hence do exactly the same thing.\footnote{Notice however, that the
+%first key will be listed as a `command key' by \pf{xkvview} and the
+%second as an `ordinary key'. See section~\ref{sec:view}.}
+%\begin{example}
+% \define@cmdkey{fam}{key}[none]{value: \cmdKV@fam@key}
+% \define@key{fam}{key}[none]{\def\cmdKV@fam@key{#1}value: \cmdKV@fam@key}
+%\end{example}
+%The value |none| is again the default value that will be submitted
+%to the key macro when the user didn't supply a value. (See also
+%section~\ref{sec:odefine} for more information.)
+%
+%The following two lines also implement a key with the same key macro.
+%\begin{example}
+% \define@cmdkey{fam}[my@]{key}[none]{value: \my@key}
+% \define@key{fam}{key}[none]{\def\my@key{#1}value: \my@key}
+%\end{example}
+%Note that the key macro itself in the examples above is still
+%|\KV@fam@key|, just as in the previous example.
+%
+%A lot of packages define keys that only save their value to a macro
+%so that it can be used later. Using the macro above, one can save
+%some tokens in the package. Some more tokens can be saved by using
+%the following macro.
+%\begin{command}
+% `\cs{define@cmdkeys}\oarg{prefix}\marg{family}\oarg{mp}\marg{keys}\oarg{default}'
+%\end{command}
+%\DescribeMacro{\define@cmdkeys}
+%This repeatedly calls (an internal of) |\define@cmdkey| for all keys
+%in the list of \meta{keys}. Note that it is not possible to specify
+%a custom key function for the keys created by this command. The only
+%function of those keys is to save user input in a macro. The first
+%line and the last two lines of the following example create keys
+%with the same internal key macro.
+%\begin{example}
+% \define@cmdkeys{fam}[my@]{keya,keyb}[none]
+% \define@key{fam}{keya}[none]{\def\my@keya{#1}}
+% \define@key{fam}{keyb}[none]{\def\my@keyb{#1}}
+%\end{example}
+%
+%\subsection{Choice keys}\label{sec:chdefine}
+%Choice keys allow only a limited number of different values for user
+%input. These keys are defined as follows.
+%\begin{command}
+% `\cs{define@choicekey}\oarg{pre}\marg{fam}\marg{key}\oarg{bin}\marg{al}\oarg{dft}\marg{func}'
+% `\cs{define@choicekey*}\oarg{pre}\marg{fam}\marg{key}\oarg{bin}\marg{al}\oarg{dft}\marg{func}'
+%\end{command}
+%\DescribeMacros{\define@choicekey,\define@choicekey*}
+%The keys work the same as ordinary keys, except that, before
+%executing anything, it is verified whether the user input |#1| is
+%present in the comma separated list \meta{al}. The starred version
+%first converts the input in |#1| and \meta{al} to lowercase before
+%performing the check. If the input is not allowed, an error is
+%produced and the key macro \meta{func} will not be executed. If the
+%input is allowed, the key macro \meta{func} will be executed. \meta{dft}
+%is submitted to the key macro when the user didn't supply a value
+%for the key. (See also section~\ref{sec:odefine}.)
+%
+%The optional \meta{bin} should contain either one or two control
+%sequences (macros). The first one will be used to store the user
+%input used in the input check (hence, in lowercase when the starred
+%version was used). The original user input will always be available
+%in |#1|. The second (if present) will contain the number of the
+%input in the \meta{al} list, starting from 0. The number will be set
+%to |-1| if the input was not allowed. The number can, for instance,
+%be used in a |\ifcase| statement in \meta{func}.
+%\begin{example}
+% \define@choicekey*{fam}{align}[\val\nr]{left,center,right}{%
+% \ifcase\nr\relax
+% \raggedright
+% \or
+% \centering
+% \or
+% \raggedleft
+% \fi
+% }
+%\end{example}
+%The example above only allows input values |left|, |center| and
+%|right|. Notice that we don't need a |\else| case in the key macro
+%above as the macro will not be executed when the input was not
+%allowed.
+%
+%\begin{command}
+% `\cs{define@choicekey+}\oarg{pre}\marg{fam}\marg{key}\oarg{bin}\marg{al}\oarg{dft}\marg{f1}\marg{f2}'
+% `\cs{define@choicekey*+}\oarg{pre}\marg{fam}\marg{key}\oarg{bin}\marg{al}\oarg{dft}\marg{f1}\marg{f2}'
+%\end{command}
+%\DescribeMacros{\define@choicekey+,\define@choicekey*+}
+%These macros operate as their counterparts without the |+|, but
+%allow for specifying two key macros. \meta{f1} will be executed when
+%the input was correct and \meta{f2} will be executed when the input
+%was not allowed. Again, the starred version executes the check after
+%converting user input and \meta{al} to lowercase.
+%\begin{example}
+% \define@choicekey*+{fam}{align}[\val\nr]{left,center,right}{%
+% \ifcase\nr\relax
+% \raggedright
+% \or
+% \centering
+% \or
+% \raggedleft
+% \fi
+% }{%
+% \PackageWarning{mypack}{erroneous input ignored}%
+% }
+%\end{example}
+%The example above defines a key that is similar as the one in the
+%previous example, but when input is not allowed, it will not
+%generate a standard \pf{xkeyval} warning, but will execute a custom
+%function, which, in this case, generates a warning.
+%
+%\begin{command}
+% `\cs{XKV@cc}\oarg{bin}\marg{input}\marg{al}\marg{func}'
+% `\cs{XKV@cc*}\oarg{bin}\marg{input}\marg{al}\marg{func}'
+% `\cs{XKV@cc+}\oarg{bin}\marg{input}\marg{al}\marg{func1}\marg{func2}'
+% `\cs{XKV@cc*+}\oarg{bin}\marg{input}\marg{al}\marg{func1}\marg{func2}'
+%\end{command}
+%\DescribeMacros{\XKV@cc,\XKV@cc*,\XKV@cc+,\XKV@cc*+}
+%Choice keys work by adding (an internal version\footnote{See
+%section~\ref{sec:imple} for details of the implementation of choice
+%keys.} of) the |\XKV@cc| macro to key macros. This macro has similar
+%arguments as the |\define@choicekey| macro and the optional |*| and
+%|+| have the same meaning. \meta{input} holds the input that should
+%be checked, namely, whether it is (in lowercase if |*| was used) in
+%the list \meta{al}. One can use this macro to create custom choice
+%keys. See an example below.
+%\begin{example}
+% \define@key{fam}{key}{%
+% I will first check your input, please wait.\\
+% \XKV@cc*+[\val]{#1}{true,false}{%
+% The input \val\ was correct, we proceed.\\
+% }{%
+% The input \val\ was incorrect and was ignored.\\
+% }%
+% I finished the input check.
+% }
+%\end{example}
+%Try to find out why this key cannot be defined with |\define@boolkey|
+%which is introduced in the next section.
+%
+%\subsection{Boolean keys}\label{sec:bdefine}
+%\changes{v1.5}{2004/09/27}{Added boolean keys}
+%This section describes boolean keys which can be either true or
+%false. A boolean key is a special version of a choice key (see
+%section~\ref{sec:chdefine}), where \meta{al} takes the value
+%|true,false| and comparisons are always done in lowercase mode (so,
+%|True| is allowed input).
+%\begin{command}
+% `\cs{define@boolkey}\oarg{pre}\marg{fam}\oarg{mp}\marg{key}\oarg{default}\marg{func}'
+% `\cs{define@boolkey+}\oarg{pre}\marg{fam}\oarg{mp}\marg{key}\oarg{default}\marg{func1}\marg{func2}'
+%\end{command}
+%\DescribeMacros{\define@boolkey,\define@boolkey+}
+%This creates a boolean of the form
+%|\if|\meta{pre}|@|\meta{family}|@|\meta{key}\footref{foot:1}\footnote{
+%When you want to use this macro directly, either make sure that
+%neither of the input parameters contain characters with a catcode
+%different from 11 (hence no \texttt{-} for instance), reset the
+%catcode of the offending characters internally to 11 or use
+%\texttt{\cs{csname}\dots\cs{endcsname}} to construct macro names,
+%(for instance, \texttt{\cs{csname}
+%ifpre@some-fam@key\cs{endcsname}}). See for more information
+%section~\ref{sec:macrostructs}.} if \meta{mp} is not specified,
+%using |\newif|\footnote{The \LaTeX\ of implementation \cs{newif} is
+%used because it can be used in the replacement text of a macro,
+%whereas the plain \TeX\ \cs{newif} is defined \cs{outer}.} (which
+%initiates the conditional to |\iffalse|) and a key macro of the form
+%|\|\meta{pre}|@|\meta{family}|@|\meta{key} which first checks the
+%validity of the user input. If the input was valid, it uses it to
+%set the boolean and afterwards, it executes \meta{func}. If the
+%input was invalid, it will not set the boolean and \pf{xkeyval} will
+%generate an error. If \meta{mp} is specified, it will create boolean
+%of the form |\if|\meta{mp}\meta{key} (compare to command keys in
+%section~\ref{sec:cdefine}). The value \meta{default} will be used by
+%the key macro when the user didn't submit a value to the key.
+%(See also section~\ref{sec:odefine}.)
+%
+%If the |+| version of the macro is used, one can specify two key
+%macros. If user input is valid, the macro will set the boolean and
+%executes \meta{func1}. Otherwise, it will not set the boolean and
+%execute \meta{func2}.
+%\begin{example}
+% \define@boolkey{fam}[my@]{frame}{}
+% \define@boolkey+{fam}{shadow}{%
+% \ifKV@fam@shadow
+% \PackageInfo{mypack}{turning shadows on}%
+% \else
+% \PackageInfo{mypack}{turning shadows off}%
+% \fi
+% }{%
+% \PackageWarning{mypack}{erroneous input ignored}%
+% }
+%\end{example}
+%The first example creates the boolean |\ifmy@frame| and defines
+%the key macro |\KV@fam@frame| to only set the boolean (if input is
+%correct). The second key informs the user about changed settings or
+%produces a warning when input was incorrect.
+%
+%One can also define multiple boolean keys with a single command.
+%\begin{command}
+% `\cs{define@boolkeys}\oarg{pre}\marg{fam}\oarg{mp}\marg{keys}\oarg{default}'
+%\end{command}
+%\DescribeMacro{\define@boolkeys}
+%This macro creates a boolean key for every entry in the list
+%\meta{keys}. As with the command |\define@cmdkeys|, the individual keys cannot
+%have a custom function. The boolean keys created with this command
+%are only meant to set the state of the boolean using the user input.
+%Concluding,
+%\begin{example}
+% \define@boolkeys{fam}[my@]{keya,keyb,keyc}
+%\end{example}
+%is an abbreviation for
+%\begin{example}
+% \define@boolkey{fam}[my@]{keya}{}
+% \define@boolkey{fam}[my@]{keyb}{}
+% \define@boolkey{fam}[my@]{keyc}{}
+%\end{example}
+%
+%\subsection{Checking keys}\label{sec:check}
+%\changes{v1.7}{2004/11/25}{Changed name of \cs{XKV@ifku}}
+%\begin{command}
+% `\cs{key@ifundefined}\oarg{prefix}\marg{families}\marg{key}\marg{undefined}\marg{defined}'
+%\end{command}
+%\DescribeMacro{\key@ifundefined}
+%This macro executes \meta{undefined} when \meta{key} is not defined
+%in a family listed in \meta{families} using \meta{prefix} (which is
+%|KV| by default) and \meta{defined} when it is. If \meta{defined} is
+%executed, |\XKV@tfam| holds the first family in the list \meta{families}
+%that holds \meta{key}. If \meta{undefined} is executed, |\XKV@tfam|
+%contains the last family of the list \meta{families}.
+%\begin{example}
+% \key@ifundefined[my]{familya,familyb}{keya}{`keya' not defined}{`keya' defined}
+%\end{example}
+%This example results in |`keya' defined| and |\XKV@tfam| holds |familya|.
+%
+%\subsection{Disabling keys}\label{sec:disable}
+%\changes{v1.7}{2004/11/25}{Added \cs{disable@keys}}
+%It is also possible to disable keys after use as to prevent the key
+%from being used again.
+%
+%\begin{command}
+% `\cs{disable@keys}\oarg{prefix}\marg{family}\marg{keys}'
+%\end{command}
+%\DescribeMacro{\disable@keys}
+%When you disable a key, the use of this key will produce a warning
+%in the log file. Disabling a key that hasn't been defined will result
+%in an error message.
+%\begin{example}
+% \disable@keys[my]{familya}{keya,keyb}
+%\end{example}
+%This would make |keya| and |keyb| produce a warning when one tries to
+%set these keys.
+%
+%\section{Setting keys}\label{sec:setkeys}
+%\subsection{The user interface}
+%\changes{v1.4}{2004/08/24}{Added prefix options to macros}
+%This section describes the available macros for setting keys. All of
+%the macros in this section have an optional argument \meta{prefix}
+%which determines part of the form of the keys that the macros will
+%be looking for. See section~\ref{sec:define}. This optional argument
+%takes the value |KV| by default.
+%
+%\begin{command}
+% `\cs{setkeys}\oarg{prefix}\marg{families}\oarg{na}\marg{keys}'
+%\end{command}
+%\DescribeMacro{\setkeys}
+%This macro sets keys of the form
+%|\|\meta{prefix}|@|\meta{family}|@|\meta{key}\footref{foot:1} where \meta{family} is
+%an element of the list \meta{families} and |key| is an element of
+%the options list \meta{keys} and not of \meta{na}. The latter list
+%can be used to specify keys that should be ignored by the macro. If
+%a key is defined by more families in the list \meta{families}, the
+%first family from the list defining the key will set it. No errors
+%are produced when \meta{keys} is empty. If \meta{family} is empty,
+%the macro will set keys of the form |\|\meta{prefix}|@|\meta{key}.
+%If \meta{prefix} is specified and empty, the macro will set keys of
+%the form |\|\meta{family}|@|\meta{key}. If both \meta{prefix} and
+%\meta{family} are empty, the macro will set keys of the form
+%|\|\meta{key}.
+%\begin{example}
+% \setkeys[my]{familya,familyb}{keya=test}
+% \setkeys[my]{familya,familyb}{keyb=test}
+% \setkeys[my]{familyb,familya}{keyb=test}
+%\end{example}
+%In the example above, line 1 will set |keya| in family |familya|.
+%This effectively means that the value |test| will be submitted to the
+%key macro |\my@familya@keya|. The next line will set |keyb| in
+%|familya|. The last one sets |keyb| in family |familyb|. As the keys
+%used here, directly output their value, the above code results in
+%typesetting the word |test| three times.
+%
+%When input is lacking for a key, |\setkeys| will check whether there
+%is a default value for that key that can be used instead. If that is
+%not the case, an error message will be generated. See also
+%section~\ref{sec:define}.
+%\begin{example}
+% \setkeys[my]{familya}{keya}
+% \setkeys[my]{familya}{keyb}
+%\end{example}
+%The first line of the example above does not generate an error as this
+%key has been defined with a default value (see section~\ref{sec:odefine}).
+%The second line does generate an error message. See also section~\ref{sec:errors}
+%for all possible error messages generated by \pf{xkeyval}.
+%
+%When you want to use commas or equality signs in the value of a key,
+%surround the value by braces, as shown in the example below.
+%\begin{example}
+% \setkeys[my]{familya}{keya={some=text,other=text}}
+%\end{example}
+%
+%It is possible to nest |\setkeys| commands in other |\setkeys| commands
+%or in key definitions. The following, for instance,
+%\begin{example}
+% \define@key[my]{familyb}{keyc}{#1}
+% \setkeys[my]{familyb}{keyc=a\setkeys[my]{familya}{keya=~and b},keyb=~and c}
+%\end{example}
+%returns |a and b and c|.
+%
+%\begin{command}
+% `\cs{setkeys*}\oarg{prefix}\marg{families}\oarg{na}\marg{keys}'
+%\end{command}
+%\DescribeMacro{\setkeys*}
+%The starred version of |\setkeys| sets keys which it can locate in
+%the given families and will not produce errors when it cannot find a
+%key. Instead, these keys and their values will be appended to a list
+%of remaining keys in the macro |\XKV@rm| after the use of
+%|\setkeys*|. Keys listed in \meta{na} will be ignored fully and
+%will not be appended to the |\XKV@rm| list.
+%\begin{example}
+% \setkeys*[my]{familyb}{keya=test}
+%\end{example}
+%Since |keya| is not defined in |familyb|, the value in the example
+%above will be stored in |\XKV@rm| (so |\XKV@rm| expands to
+%|keya=test|) for later use and no errors are raised.
+%
+%\begin{command}
+% `\cs{setrmkeys}\oarg{prefix}\marg{families}\oarg{na}'
+%\end{command}
+%\DescribeMacro{\setrmkeys}
+%The macro |\setrmkeys| sets the remaining keys given by the list
+%|\XKV@rm| stored previously by a |\setkeys*| (or |\setrmkeys*|)
+%command in \meta{families}. \meta{na} again lists keys that should
+%be ignored. It will produce an error when a key cannot be located.
+%\begin{example}
+% \setrmkeys[my]{familya}
+%\end{example}
+%This submits |keya=test| from the previous
+%|\setkeys*| command to |familya|. |keya| will be set.
+%
+%\begin{command}
+% `\cs{setrmkeys*}\oarg{prefix}\marg{families}\oarg{na}'
+%\end{command}
+%\DescribeMacro{\setrmkeys*}
+%The macro |\setrmkeys*| acts as the |\setrmkeys| macro but now,
+%as with |\setkeys*|, it ignores keys that it cannot find and puts
+%them again on the list stored in |\XKV@rm|. Keys listed in \meta{na}
+%will be ignored fully and will not be appended to the list in
+%|\XKV@rm|.
+%\begin{example}
+% \setkeys*[my]{familyb}{keya=test}
+% \setrmkeys*[my]{familyb}
+% \setrmkeys[my]{familya}
+%\end{example}
+%In the example above, the second line tries to set |keya| in
+%|familyb| again and no errors are generated on failure. The last
+%line finally sets |keya|.
+%
+%The combination of |\setkeys*| and |\setrmkeys| can be used to
+%construct complex macros in which, for instance, a part of the keys
+%should be set in multiple families and the rest in another family or
+%set of families. Instead of splitting the keys or the inputs, the
+%user can supply all inputs in a single argument and the two macros
+%will perform the splitting and setting of keys for your macro, given
+%that the families are well chosen.
+%
+%\begin{command}
+% `\cs{setkeys+}\oarg{prefix}\marg{families}\oarg{na}\marg{keys}'
+% `\cs{setkeys*+}\oarg{prefix}\marg{families}\oarg{na}\marg{keys}'
+% `\cs{setrmkeys+}\oarg{prefix}\marg{families}\oarg{na}'
+% `\cs{setrmkeys*+}\oarg{prefix}\marg{families}\oarg{na}'
+%\end{command}
+%\changes{v1.4}{2004/08/24}{Added \texttt{+} option to macros}
+%\DescribeMacros{\setkeys+,\setkeys*+,\setkeys+,\setkeys*+}
+%These macros act as their counterparts without the |+|. However,
+%when a key in \meta{keys} is defined by multiple families, this key
+%will be set in \emph{all} families in \meta{families}. This can, for
+%instance, be used to set keys defined by your own package and by
+%another package with the same name but in different families with a
+%single command.
+%\begin{example}
+% \setkeys+[my]{familya,familyb}{keyb=test}
+%\end{example}
+%The example above sets |keyb| in both families.
+%
+%\subsection{A few details}
+%Several remarks should be made with respect to processing the user
+%input. Assuming that |keya| up to |keyd| are properly defined, one
+%could do the following.
+%\begin{example}
+% \setkeys{family}{keya= test a, keyb={test b,c,d}, , keyc=end}
+%\end{example}
+%From values consisting entirely of a |{ }| group, the outer braces
+%will be stripped off internally.\footnote{\pf{xkeyval} actually
+%strips off 3 levels of braces: one by using \pf{keyval}'s
+%\cs{KV@@sp@def} and two in internal parsings. \pf{keyval} strips off
+%only 2 levels: one by using \cs{KV@@sp@def} and one in internal
+%parsings. This difference has not yet been shown to cause problems
+%for existing packages or new implementations. If this appears to be
+%a problem in the future, effort will be done to solve it.} This
+%allows the user to `hide' any commas or equality signs that appear
+%in the value of a key. This means that when using braces around
+%|value|, \pf{xkeyval} will not terminate the |value| when it
+%encounters a comma in |value|. For instance, see the value of |keyb|
+%in the example above. The same holds for the equality sign. Notice
+%further that any spaces around the characters |=| and |,| (in the
+%top level group) are removed and that empty entries will silently be
+%ignored. This makes the example above equivalent to the example
+%below.
+%\begin{example}
+% \setkeys{family}{keya=test a,keyb={test b,c,d},keyc=end}
+%\end{example}
+%
+%Further, when executing a key macro, the following \pf{xkeyval}
+%internals are available.
+%\begin{description}
+%\item[\cs{XKV@prefix}]\mbox{}\\
+%The prefix, for instance |my|.
+%\item[\cs{XKV@fams}]\mbox{}\\
+%The list of families to search, for instance |familya,familyb|.
+%\item[\cs{XKV@tfam}]\mbox{}\\
+%The current family, for instance |familya|.
+%\item[\cs{XKV@header}]\mbox{}\\
+%The header which is a combination of the prefix and the current
+%family, for instance |my@familya@|.
+%\item[\cs{XKV@tkey}]\mbox{}\\
+%The current key name, for instance |keya|.
+%\item[\cs{XKV@na}]\mbox{}\\
+%The keys that should not be set, for instance |keyc,keyd|.
+%\end{description}
+%You can use these internals and create, for example, dynamic options
+%systems in which user input to |\setkeys| will be used to create new
+%keys which can be used in the very same |\setkeys| command. The
+%\pf{extract} package \cite{extract} provides an example for this.
+%
+%\section{Pointers}\label{sec:pointers}
+%\changes{v1.4}{2004/08/24}{Added pointer syntax}
+%\changes{v1.5}{2004/09/27}{Removed \cs{ifrecordkeyvals}}
+%\changes{v1.7}{2004/11/25}{Changed value saving mechanism}
+%\changes{v1.7}{2004/11/25}{Changed pointer mechanism}
+%The \pf{xkeyval} package provides a pointer mechanism.
+%Pointers can be used to copy values of keys. Hence, one can
+%reuse the value that has been submitted to a particular key in the
+%value of another key. This section will first describe how
+%\pf{xkeyval} can be made to save key values. After that, it will
+%explain how to use these saved values again. Notice already that the
+%commands |\savevalue|, |\gsavevalue| and |\usevalue| can only be used
+%in |\setkeys| commands.
+%
+%\subsection{Saving values}\label{sec:savevalue}
+%\DescribeMacro{\savevalue}
+%Saving a value for a particular key can be accomplished by using the
+%|\savevalue| command with the key name as
+%argument.
+%\begin{example}
+% \setkeys[my]{familya}{\savevalue{keya}=test}
+%\end{example}
+%This example will set |keya| as we have seen before, but will additionally define
+%the macro |\XKV@my@familya@keya@value| to expand to |test|. This
+%macro can be used later on by \pf{xkeyval} to replace pointers. In
+%general, values of keys will be stored in macros of the form
+%|\XKV@|\meta{prefix}|@|\meta{family}|@|\meta{key}|@value|. This implies
+%that the pointer system can only be used within the same family (and
+%prefix). We will come back to that in section~\ref{sec:usevalue}.
+%
+%\DescribeMacro{\gsavevalue}
+%Using the global version of this command, namely |\gsavevalue|,
+%will define the value macro |\XKV@my@family@key@value| globally.
+%In other words, the value macro won't survive after a
+%|\begingroup|\texttt\dots|\endgroup| construct (for instance, an
+%environment), when it has been created in this group using
+%|\savevalue| and it will survive afterwards if |\gsavevalue| is
+%used.
+%\begin{example}
+% \setkeys[my]{familya}{\gsavevalue{keya}=test}
+%\end{example}
+%This example will globally define |\XKV@my@familya@keya@value| to
+%expand to |test|.
+%
+%Actually, in most applications, package authors do not want to require
+%users to use the |\savevalue| form when using the pointer system internally.
+%To avoid this, the \pf{xkeyval} package also supplies the following commands.
+%\begin{command}
+% `\cs{savekeys}\oarg{prefix}\marg{family}\marg{keys}'
+% `\cs{gsavekeys}\oarg{prefix}\marg{family}\marg{keys}'
+%\end{command}
+%\DescribeMacros{\savekeys,\gsavekeys}
+%The |\savekeys| macro stores a list of keys for which the values
+%should always be saved to a macro of the form
+%|\XKV@|\meta{prefix}|@|\meta{family}|@save|. This will be used by
+%|\setkeys| to check whether a value should be saved or not. The
+%global version will define this internal macro globally so that the
+%settings can escape groups (and environments). The |\savekeys| macro
+%works incrementally. This means that new input will be added to an
+%existing list for the family at hand if it is not in yet.
+%\begin{example}
+% \savekeys[my]{familya}{keya,keyc}
+% \savekeys[my]{familya}{keyb,keyc}
+%\end{example}
+%The first line stores |keya,keyc| to |\XKV@my@familya@save|. The
+%next line changes the content of this macro to |keya,keyc,keyb|.
+%
+%\begin{command}
+% `\cs{delsavekeys}\oarg{prefix}\marg{family}\marg{keys}'
+% `\cs{gdelsavekeys}\oarg{prefix}\marg{family}\marg{keys}'
+% `\cs{unsavekeys}\oarg{prefix}\marg{family}'
+% `\cs{gunsavekeys}\oarg{prefix}\marg{family}'
+%\end{command}
+%\DescribeMacros{\delsavekeys,\gdelsavekeys,\unsavekeys,\gunsavekeys}
+%The |\delsavekeys| macro can be used to remove some keys from an
+%already defined list of save keys. No errors will be raised when one
+%of the keys in the list \meta{keys} was not in the list. The global
+%version |\gdelsavekeys| does the same as |\delsavekeys|, but will
+%also make the resulting list global. The |\unsavekeys| macro can be
+%used to clear the entire list of key names for which the values
+%should be saved. The macro will make
+%|\XKV@|\meta{prefix}|@|\meta{family}|@save| undefined.
+%|\gunsavekeys| is similar to |\unsavekeys| but makes the internal
+%macro undefined globally.
+%\begin{example}
+% \savekeys[my]{familya}{keya,keyb,keyc}
+% \delsavekeys[my]{familya}{keyb}
+% \unsavekeys[my]{familya}
+%\end{example}
+%The first line of this example initializes the list to contain
+%|keya,keyb,keyc|. The second line removes |keyb| from this list and
+%hence |keya,keyc| remains. The last line makes the list undefined and
+%hence clears the settings for this family.
+%
+%\DescribeMacro{\global}
+%It is important to notice that the use of the global version
+%|\gsavekeys| will only have effect on the definition of the macro
+%|\XKV@|\meta{prefix}|@|\meta{family}|@save|. It will not have an
+%effect on how the key values will actually be saved by |\setkeys|.
+%To achieve that a particular key value will be saved globally (like
+%using |\gsavevalue|), use the |\global| specifier in the |\savekeys|
+%argument.
+%\begin{example}
+% \savekeys[my]{familya}{keya,\global{keyc}}
+%\end{example}
+%This example does the following. The argument |keya,\global{keyc}|
+%is saved (locally) to |\XKV@my@familya@save|. When |keyc| is used in
+%a |\setkeys| command, the associated value will be saved globally to
+%|\XKV@my@familya@keya@value|. When |keya| is used, its value will be
+%saved locally.
+%
+%All macros discussed in this section for altering the list of save keys
+%only look at the key name. If that is the same, old content will be
+%overwritten with new content, regardless whether |\global| has been
+%used in the content. See the example below.
+%\begin{example}
+% \savekeys[my]{familya}{\global{keyb},keyc}
+% \delsavekeys[my]{familya}{keyb}
+%\end{example}
+%The first line changes the list in |\XKV@my@familya@save| from
+%|keya,\global{keyc}| to |keya,keyc,\global{keyb}|. The second line
+%changes the list to |keya,keyc|.
+%
+%\subsection{Using saved values}\label{sec:usevalue}
+%\DescribeMacro{\usevalue}
+%The syntax of a pointer is |\usevalue{keyname}| and can only be used
+%inside |\setkeys| and friends. \pf{xkeyval} will
+%replace a pointer by the value that has been saved for the key that
+%the pointer is pointing to. If no value has been saved for this key,
+%an error will be raised. The following example will demonstrate how
+%to use pointers (using the keys defined in
+%section~\ref{sec:odefine}).
+%\begin{example}
+% \setkeys[my]{familya}{\savevalue{keya}=test}
+% \setkeys[my]{familya}{keyb=\usevalue{keya}}
+%\end{example}
+%The value submitted to |keyb| points to |keya|. This has the effect
+%that the value recorded for |keya| will replace |\usevalue{keya}| and this
+%value (here |test|) will be submitted to the key macro of |keyb|.
+%
+%Since the saving of values is prefix and family specific, pointers can
+%only locate values that have been saved for keys with the same
+%prefix and family as the key for which the pointer is used. Hence this
+%\begin{example}
+% \setkeys[my]{familya}{\savevalue{keya}=test}
+% \setkeys[my]{familyb}{keyb=\usevalue{keya}}
+%\end{example}
+%will never work. An error will be raised in case a key value points
+%to a key for which the value cannot be found or has not been stored.
+%
+%It is possible to nest pointers as the next example shows.
+%\begin{example}
+% \setkeys[my]{familya}{\savevalue{keya}=test}
+% \setkeys[my]{familya}{\savevalue{keyb}=\usevalue{keya}}
+% \setkeys[my]{familya}{keyc=\usevalue{keyb}}
+%\end{example}
+%This works as follows. First \pf{xkeyval} records the value |test|
+%in a macro. Then, |keyb| uses that value. Besides that, the value
+%submitted to |keyb|, namely |\usevalue{keya}| will be recorded in another
+%macro. Finally, |keyc| will use the value recorded previously for
+%|keyb|, namely |\usevalue{keya}|. That in turn points to the value saved for
+%|keya| and that value will be used.
+%
+%It is important to stress that the pointer replacement will be done
+%before \TeX\ or \LaTeX\ performs the expansion of the key macro and
+%its argument (which is the value that has been submitted to the
+%key). This allows pointers to be used in almost any application. (The
+%exception is grouped material, to which we will come back later.)
+%When programming keys (using |\define@key| and friends), you won't
+%have to worry about the expansion of the pointers which might be
+%submitted to your keys. The value that will be submitted to your key
+%macro in the end, will not contain pointers. These have
+%already been expanded and been replaced by the saved values.
+%
+%A word of caution is necessary. You might get into an infinite
+%loop if pointers are not applied with care, as the examples below
+%show. The first example shows a direct back link.
+%\begin{example}
+% \setkeys[my]{familya}{\savevalue{keya}=\usevalue{keya}}
+%\end{example}
+%The second example shows an indirect back link.
+%\begin{example}
+% \setkeys[my]{familya}{\savevalue{keya}=test}
+% \setkeys[my]{familya}{\savevalue{keyb}=\usevalue{keya}}
+% \setkeys[my]{familya}{\savevalue{keya}=\usevalue{keyb}}
+%\end{example}
+%In these cases, an error will be issued and further pointer replacement
+%is canceled.
+%
+%As mentioned already, pointer replacement does not work inside
+%grouped material, |{...}|, if this group is not around the entire
+%value (since that will be stripped off, see section~\ref{sec:intro}).
+%The following, for instance, will not work.
+%\begin{example}
+% \setkeys[my]{familya}{\savevalue{keya}=test}
+% \setkeys[my]{familya}{keyb=\parbox{2cm}{\usevalue{keya}}}
+%\end{example}
+%The following provides a working alternative for this situation.
+%\begin{example}
+% \setkeys[my]{familya}{\savevalue{keya}=test}
+% \setkeys[my]{familya}{keyb=\begin{minipage}{2cm}\usevalue{keya}\end{minipage}}
+%\end{example}
+%In case there is no appropriate alternative, we can work around this
+%restriction, for instance by using a value macro directly.
+%\begin{example}
+% \setkeys[my]{familya}{\savevalue{keya}=test}
+% \setkeys[my]{familya}{keyb=\parbox{2cm}{\XKV@my@familya@keya@value}}
+%\end{example}
+%When no value has been saved for |keya|, the macro
+%|\XKV@my@familya@keya@value| is undefined. Hence one might want to
+%do a preliminary check to be sure that the macro exists.
+%
+%Pointers can also be used in default values. We finish this section
+%with an example which demonstrates this.
+%\begin{example}
+% \define@key{fam}{keya}{keya: #1}
+% \define@key{fam}{keyb}[\usevalue{keya}]{keyb: #1}
+% \define@key{fam}{keyc}[\usevalue{keyb}]{keyc: #1}
+% \setkeys{fam}{\savevalue{keya}=test}
+% \setkeys{fam}{\savevalue{keyb}}
+% \setkeys{fam}{keyc}
+%\end{example}
+%Since user input is lacking in the final two commands, the default
+%value defined for those keys will be used. In the first case, the
+%default value points to |keya|, which results in the value |test|.
+%In the second case, the pointer points to |keyb|, which points to
+%|keya| (since its value has been saved now) and hence also in the
+%final command, the value |test| will be submitted to the key macro
+%of |keyc|.
+%
+%\section{Presetting keys}\label{sec:preset}
+%\changes{v1.5}{2004/09/27}{Added preset system}
+%In contrast to the default value system where users are required to
+%specify the key without a value to assign it its default value, the
+%presetting system does not require this. Keys which are preset will
+%be set automatically by |\setkeys| when the user didn't use those
+%keys in the |\setkeys| command. When users did use the keys which
+%are also preset, |\setkeys| will avoid setting them again. This
+%section again uses the key definitions of section~\ref{sec:odefine}
+%in examples.
+%
+%\begin{command}
+% `\cs{presetkeys}\oarg{prefix}\marg{family}\marg{head keys}\marg{tail keys}'
+% `\cs{gpresetkeys}\oarg{prefix}\marg{family}\marg{head keys}\marg{tail keys}'
+%\end{command}
+%\DescribeMacros{\presetkeys,\gpresetkeys}
+%This macro will save \meta{head keys} to
+%|\XKV@|\meta{prefix}|@|\meta{family}|@preseth| and \meta{tail keys}
+%to |\XKV@|\meta{prefix}|@|\meta{family}|@presett|. Savings are done
+%locally by |\presetkeys| and globally by |\gpresetkeys| (compare
+%|\savekeys| and |\gsavekeys|, section~\ref{sec:savevalue}). The
+%saved macros will be used by |\setkeys|, when they are defined,
+%whenever \meta{family} is used in the \meta{families} argument of
+%|\setkeys|. Head keys will be set before setting user keys, tail
+%keys will be set afterwards. However, if a key appears in the user
+%input, this particular key will not be set by any of the preset
+%keys.
+%
+%The macros work incrementally. This means that new input for a
+%particular key replaces already present settings for this key. If no
+%settings were present yet, the new input for this key will be
+%appended to the end of the existing list. The replacement ignores
+%the fact whether a |\savevalue| or an |=| has been specified in the key
+%input. We could do the following.
+%\begin{example}
+% \presetkeys{fam}{keya=red,\savevalue{keyb},keyc}{}
+% \presetkeys{fam}{\savevalue{keya},keyb=red,keyd}{}
+%\end{example}
+%After the first line of the example, the macro |\XKV@KV@fam@preseth|
+%will contain |keya=red,\savevalue{keyb},keyc|. After the second line of the
+%example, the macro will contain |\savevalue{keya},keyb=red,keyc,keyd|.
+%The \meta{tail keys} remain empty throughout the example.
+%
+%\begin{command}
+% `\cs{delpresetkeys}\oarg{prefix}\marg{family}\marg{head keys}\marg{tail keys}'
+% `\cs{gdelpresetkeys}\oarg{prefix}\marg{family}\marg{head keys}\marg{tail keys}'
+%\end{command}
+%\DescribeMacros{\delpresetkeys,\gdelpresetkeys}
+%These commands can be used to (globally) delete entries from the
+%presets by specifying the key names for which the presets should be
+%deleted. Continuing the previous example, we could do the following.
+%\begin{example}
+% \delpresetkeys{fam}{keya,keyb}{}
+%\end{example}
+%This redefines the list of head presets |\XKV@KV@fam@preseth| to
+%contain |keyc,keyd|. As can be seen from this example, the exact
+%use of a key name is irrelevant for successful deletion.
+%
+%\begin{command}
+% `\cs{unpresetkeys}\oarg{prefix}\marg{family}'
+% `\cs{gunpresetkeys}\oarg{prefix}\marg{family}'
+%\end{command}
+%\DescribeMacros{\unpresetkeys,\gunpresetkeys}
+%These commands clear the presets for \meta{family} and works just as
+%|\unsavekeys|. It makes
+%|\XKV@|\meta{prefix}|@|\meta{family}|@preseth| and
+%|\XKV@|\meta{prefix}|@|\meta{family}|@presett| undefined. The global
+%version will make the macros undefined globally.
+%
+%Two type of problems in relation to pointers could appear when
+%specifying head and tail keys incorrectly. This will be demonstrated
+%with two examples. In the first example, we would like to set |keya|
+%to |blue| and |keyb| to copy the value of |keya|, also when the user
+%has changed the preset value of |keya|. Say that we implement the
+%following.
+%\begin{example}
+% \savekeys[my]{familya}{keya}
+% \presetkeys[my]{familya}{keya=blue,keyb=\usevalue{keya}}{}
+% \setkeys[my]{familya}{keya=red}
+%\end{example}
+%This will come down to executing
+%\begin{example}
+% \savekeys[my]{familya}{keya}
+% \setkeys[my]{familya}{keyb=\usevalue{keya},keya=red}
+%\end{example}
+%since |keya| has been specified by the user. At best, |keyb| will
+%copy a probably wrong value of |keya|. In the case that no value for
+%|keya| has been saved before, we get an error. We observe that the
+%order of keys in the simplified |\setkeys| command is wrong. This
+%example shows that the |keyb=\usevalue{keya}| should have been in the
+%tail keys, so that it can copy the user input to |keya|.
+%
+%The following example shows what can go wrong when using presets
+%incorrectly and when |\setkeys| contains pointers.
+%\begin{example}
+% \savekeys[my]{familya}{keya}
+% \presetkeys[my]{familya}{}{keya=red}
+% \setkeys[my]{familya}{keyb=\usevalue{keya}}
+%\end{example}
+%This will come down to executing the following.
+%\begin{example}
+% \savekeys[my]{familya}{keya}
+% \setkeys[my]{familya}{keyb=\usevalue{keya},keya=red}
+%\end{example}
+%This results in exactly the same situation as we have seen in the
+%previous example and hence the same conclusion holds. In this case,
+%we conclude that the |keya=red| argument should have been specified
+%in the head keys of the |\presetkeys| command so that |keyb| can
+%copy the value of |keya|.
+%
+%For most applications, one could use the rule of thumb that preset
+%keys containing pointers should go in the tail keys. All other keys
+%should go in head keys. There might, however, be applications
+%thinkable in which one would like to implement the preset system as
+%shown in the two examples above, for instance to easily retrieve
+%values used in the last use of a macro or environment. However, make
+%sure that keys in that case receive an initialization in order to
+%avoid errors of missing values.
+%
+%For completeness, the working examples are below.
+%\begin{example}
+% \savekeys[my]{familya}{keya}
+% \presetkeys[my]{familya}{keya=blue}{keyb=\usevalue{keya}}
+% \setkeys[my]{familya}{keya=red}
+% \presetkeys[my]{familya}{keya=red}{}
+% \setkeys[my]{familya}{keyb=\usevalue{keya}}
+%\end{example}
+%Other examples can be found in the example files. See section~\ref{sec:sande}.
+%
+%\section{Package option processing}\label{sec:options}
+%\changes{v1.4}{2004/08/24}{Added prefix options to macros}
+%The macros in this section can be used to build \LaTeX\ class or
+%package options systems using \pf{xkeyval}. These are comparable to
+%the standard \LaTeX\ macros without the trailing |X|. See for more
+%information about these \LaTeX\ macros the documentation of the
+%source \cite{LaTeXbase} or a \LaTeX\ manual (for instance, the
+%\LaTeX\ Companion \cite{companion}). The macros in this section have
+%been built using |\define@key| and |\setkeys| and are not
+%available to \TeX\ users.
+%
+%The macros below allow for specifying the \meta{family} (or
+%\meta{families}) as an optional
+%argument. This could be useful if you want to define global options
+%which can be reused later (and set locally by the user) in a macro or
+%environment that you define. If no \meta{family} (or
+%\meta{families}) is specified, the macro will insert the default
+%family name which is the filename of the file that is calling the
+%macros. The macros in this section also allow for setting an
+%optional prefix. When using the filename as family, uniqueness of
+%key macros is already guaranteed. In that case, you can omit the
+%optional \meta{prefix}. However, when you use a custom prefix for
+%other keys in your package and you want to be able to set all of
+%the keys later with a single command, you can use the custom prefix
+%also for the class or package options system.
+%
+%Note that both \oarg{arg} and \larg{arg} denote optional arguments
+%to the macros in this section. This syntax is used to identify the
+%different optional arguments when they appear next to each other.
+%
+%\begin{command}
+% `\cs{DeclareOptionX}\oarg{prefix}\larg{family}\marg{key}\oarg{default}\marg{function}'
+%\end{command}
+%\DescribeMacro{\DeclareOptionX}
+%Declares an option (i.e., a key, which can also be used later on in
+%the package in |\setkeys| and friends). This macro is comparable to the
+%standard \LaTeX\ macro |\DeclareOption|, but with this command, the
+%user can pass a value to the option as well. Reading that value can
+%be done by using |#1| in \meta{function}. This will contain
+%\meta{default} when no value has been specified for the key. The
+%value of the optional argument \meta{default} is empty by default.
+%This implies that when the user does not assign a value to
+%\meta{key} and when no default value has been defined, no error will
+%be produced. The optional argument \meta{family} can be used to
+%specify a custom family for the key. When the argument is not used,
+%the macro will insert the default family name.
+%\begin{example}
+% \newif\iflandscape
+% \DeclareOptionX{landscape}{\landscapetrue}
+% \DeclareOptionX{parindent}[20pt]{\setlength\parindent{#1}}
+%\end{example}
+%Assuming that the file containing the example above
+%is called |myclass.cls|, the example is equivalent to
+%\begin{example}
+% \newif\iflandscape
+% \define@key{myclass.cls}{landscape}[]{\landscapetrue}
+% \define@key{myclass.cls}{parindent}[20pt]{\setlength\parindent{#1}}
+%\end{example}
+%Notice that an empty default value has been inserted by \pf{xkeyval}
+%for the |landscape| option. This allows for the usual \LaTeX\ options
+%use like
+%\begin{example}
+% \documentclass[landscape]{myclass}
+%\end{example}
+%without raising \texttt{No value specified for key `landscape'} errors.
+%
+%These examples also show that one can also use |\define@key| (or
+%friends, see section~\ref{sec:define}) to define class or package
+%options. The macros presented here are supplied for the ease of
+%package programmers wanting to convert the options section of their
+%package to use \pf{xkeyval}.
+%
+%\begin{command}
+% `\cs{DeclareOptionX*}\marg{function}'
+%\end{command}
+%\DescribeMacro{\DeclareOptionX*}
+%This macro can be used to process any unknown inputs. It is
+%comparable to the \LaTeX\ macro |\DeclareOption*|. Use
+%|\CurrentOption| within this macro to get the entire input from
+%which the key is unknown, for instance |unknownkey=value| or
+%|somevalue|. These values (possibly including a key) could for
+%example be passed on to another class or package or could be used as
+%an extra class or package option specifying for instance a style
+%that should be loaded.
+%\begin{example}
+% \DeclareOptionX*{\PackageWarning{mypackage}{`\CurrentOption' ignored}}
+%\end{example}
+%The example produces a warning when the user issues an option
+%that has not been declared.
+%
+%\begin{command}
+% `\cs{ExecuteOptionsX}\oarg{prefix}\larg{families}\oarg{na}\marg{keys}'
+%\end{command}
+%\DescribeMacro{\ExecuteOptionsX}
+%This macro sets keys created by |\DeclareOptionX| and is basically a
+%copy of |\setkeys|. The optional argument \meta{na} specifies keys
+%that should be ignored. The optional argument \meta{families} can be
+%used to specify a list of families which define \meta{keys}. When
+%the argument is not used, the macro will insert the default family
+%name. This macro will not use the declaration done by |\DeclareOptionX*|
+%when undeclared options appear in its argument. Instead, in this case
+%the macro will raise an error. This mimics \LaTeX's |\ExecuteOptions|'
+%behavior.
+%\begin{example}
+% \ExecuteOptionsX{parindent=0pt}
+%\end{example}
+%This initializes |\parindent| to |0pt|.
+%
+%\begin{command}
+% `\cs{ProcessOptionsX}\oarg{prefix}\larg{families}\oarg{na}'
+%\end{command}
+%\DescribeMacro{\ProcessOptionsX}
+%This macro processes the keys and values passed by the user to the
+%class or package. The optional argument \meta{na} can be used to
+%specify keys that should be ignored. The optional argument
+%\meta{families} can be used to specify the families that have been
+%used to define the keys. Note that this macro will not protect
+%macros in the user inputs (like |\thepage|) as will be explained in
+%section~\ref{sec:macrooptions}. When used in a class file, this macro
+%will ignore unknown keys or options. This allows
+%the user to use global options in the |\documentclass| command which
+%can be copied by packages loaded afterwards.
+%
+%\begin{command}
+% `\cs{ProcessOptionsX*}\oarg{prefix}\larg{families}\oarg{na}'
+%\end{command}
+%\label{macro:poxstar}
+%\DescribeMacro{\ProcessOptionsX*}
+%The starred version works like |\ProcessOptionsX| except that it also
+%copies user input from the |\documentclass| command. When the user
+%specifies an option in the document class which also exists in the
+%local family (or families) of the package issuing
+%|\ProcessOptionsX*|, the local key will be set as well. In this
+%case, |#1| in the |\DeclareOptionX| macro will contain the value
+%entered in the |\documentclass| command for this key. First the
+%global options from |\documentclass| will set local keys and
+%afterwards, the local options, specified with |\usepackage|,
+%|\RequirePackage| or |\LoadClass| (or friends), will set local keys,
+%which could overwrite the global options again, depending on the way
+%the options sections are constructed. This macro reduces to
+%|\ProcessOptionsX| only when issued from the class which forms the
+%document class for the file at hand to avoid setting the same
+%options twice, but not for classes loaded later using for instance
+%|\LoadClass|. Global options that do not have a counterpart in local
+%families of a package or class will be skipped.
+%
+%It should be noted that these implementations differ from the
+%\LaTeX\ implementations of |\ProcessOptions| and |\ProcessOptions*|.
+%The difference is in copying the global options. The \LaTeX\
+%commands always copy global options if possible. As a package author
+%doesn't know beforehand which document class will be used and with
+%which options, the options declared by the author might show some
+%unwanted interactions with the global options. When the class and
+%the package share the same option, specifying this option in the
+%|\documentclass| command will force the package to use that option
+%as well. With |\ProcessOptionsX|, \pf{xkeyval} offers a package
+%author to become fully independent of the global options and be sure
+%to avoid conflicts with any class. Have a look at the example class,
+%style and |.tex| file below and observe the effect of changing to
+%|\ProcessOptionsX*| in the style file.\footnote{See
+%section~\ref{sec:bdefine} for information about
+%\cs{define@boolkey}.}
+%\begin{minipage}[t]{.49\linewidth}
+%\begin{example}
+% % myclass.cls
+% \RequirePackage{xkeyval}
+% \define@boolkey{myclass.cls}%
+% [cls]{bool}{}
+% \ProcessOptionsX
+% \LoadClass{article
+%\end{example}
+%\end{minipage}
+%\hfill
+%\begin{minipage}[t]{.49\linewidth}
+%\begin{example}
+% % mypack.sty
+% \define@boolkey{mypack.sty}%
+% [pkg]{bool}{}
+% \ProcessOptionsX
+%\end{example}
+%\end{minipage}
+%\begin{example}
+% % test.tex
+% \documentclass[bool=true]{myclass}
+% \usepackage{mypack}
+% \begin{document}\parindent0pt
+% \ifclsbool class boolean true \else class boolean false\fi\\
+% \ifpkgbool package boolean true \else package boolean false\fi
+% \end{document}
+%\end{example}
+%See section~\ref{sec:sande} for more examples.
+%
+%The use of |\ProcessOptionsX*| in a class file might be tricky since
+%the class could also be used as a basis for another package or class
+%using |\LoadClass|. In that case, depending on the options system of
+%the document class, the behavior of the class loaded with
+%|\LoadClass| could change compared to the situation when it is
+%loaded by |\documentclass|. But since it is technically possible to
+%create two classes that cooperate, the \pf{xkeyval} package allows
+%for the usage of |\ProcessOptionsX*| in class files. Notice that
+%using \LaTeX's |\ProcessOptions| or |\ProcessOptions*|, a class file
+%cannot copy document class options.
+%
+%In case you want to verify whether your class is loaded with
+%|\documentclass| or |\LoadClass|, you can use the |\XKV@documentclass|
+%macro which contains the current document class.
+%
+%A final remark concerns the use of expandable macros in class or
+%package options values. Due to the construction of the \LaTeX\
+%option processing mechanism, this is not possible. However, the
+%\pf{xkeyval} bundle includes a patch for the \LaTeX\ kernel which
+%solves this problem. See section~\ref{sec:ltxpatch} for more
+%information.
+%
+%\section{List of macro structures}\label{sec:macrostructs}
+%This section provides a list of all reserved internal macro structures used
+%for key processing. Here |pre| denotes a prefix, |fam| denotes a
+%family and |key| denotes a key. These vary per application. The
+%other parts in internal macro names are constant. The macros with
+%additional |XKV| prefix are protected in the sense that all \pf{xkeyval}
+%macros disallow the use of the |XKV| prefix. Package authors
+%using \pf{xkeyval} are responsible for protecting the other types of
+%internal macros.
+%
+%\begin{description}
+%\item[\cs{pre@fam@key}]\mbox{}\\
+%Key macro. This macro takes one argument. This macro will execute
+%the \meta{function} of |\define@key| (and friends) on the value
+%submitted to the key macro through |\setkeys|.
+%\item[\cs{cmdpre@fam@key}]\indent\\
+%The macro which is used by |\define@cmdkey| to store user input in
+%when no custom macro prefix was specified.
+%\item[\cs{ifpre@fam@key}, \cs{pre@fam@keytrue}, \cs{pre@fam@keyfalse}]\indent\\
+%The conditional created by |\define@boolkey| with parameters |pre|,
+%|fam| and |key| if no custom macro prefix was specified. The
+%|true| and |false| macros are used to set the conditional to
+%|\iftrue| and |\iffalse| respectively.
+%\item[\cs{pre@fam@key@default}]\indent\\
+%Default value macro. This macro expands to |\pre@fam@key{default value}|.
+%This macro is defined through |\define@key| and friends.
+%\item[\cs{XKV@pre@fam@key@value}]\indent\\
+%This macro is used to store the value that has been submitted
+%through |\setkeys| to the key macro (without replacing pointers).
+%\item[\cs{XKV@pre@fam@save}]\indent\\
+%Contains the names of the keys that should always be saved when they
+%appear in a |\setkeys| command. This macro is defined by
+%|\savekeys|.
+%\item[\cs{XKV@pre@fam@preseth}]\indent\\
+%Contains the head presets. These will be submitted to |\setkeys|
+%before setting user input. Defined by |\presetkeys|.
+%\item[\cs{XKV@pre@fam@presett}]\indent\\
+%Contains the tail presets. These will be submitted to |\setkeys|
+%after setting user input. Defined by |\presetkeys|.
+%\end{description}
+%
+%An important remark should be made. Most of the macros listed above
+%will be constructed by \pf{xkeyval} internally using
+%|\csname...\endcsname|. Hence almost any input to the macros defined
+%by this package is possible. However, some internal macros might be
+%used outside \pf{xkeyval} macros as well, for instance the macros of
+%the form |\ifpre@fam@key| and |\cmdpre@fam@key|. To be able to use
+%these macros yourself, none of the input parameters should contain
+%non-letter characters. If you feel that this is somehow necessary
+%anyway, there are several strategies to make things work.
+%
+%Let us consider as example the following situation (notice the hyphen
+%|-| in the family name).
+%\begin{example}
+% \define@boolkey{some-fam}{myif}
+% \setkeys{some-fam}{myif=false}
+%\end{example}
+%Using these keys in a |\setkeys| command is not a problem at all.
+%However, if you want to use the |\ifKV@some-fam@myif| command itself,
+%you can do either
+%\begin{example}
+% \edef\savedhyphencatcode{\the\catcode`\-}%
+% \catcode`\-=11\relax
+% \def\mymacro{%
+% \ifKV@some-fam@myif
+% % true case
+% \else
+% % false case
+% \fi}
+% \catcode`\-=\savedhyphencatcode
+%\end{example}
+%or
+%\begin{example}
+% \def\mymacro{%
+% \csname ifKV@some-fam@myif\endcsname
+% % true case
+% \else
+% % false case
+% \fi}
+%\end{example}
+%
+%\section{Warnings and errors}\label{sec:errors}
+%There are several points where \pf{xkeyval} performs a check and
+%could produce a warning or an error. All possible warnings or and
+%error messages are listed below with an explanation. Here |pre|
+%denotes a prefix, |name| denotes the name of a key, |fam| denotes a
+%family, |fams| denotes a list of families and |val| denotes some
+%value. These vary per application. Note that messages 1 to 7 could
+%result from erroneous key setting through |\setkeys|, |\setrmkeys|,
+%|\ExecuteOptionsX| and |\ProcessOptionsX|.
+%
+%\begin{description}
+%\item[\normalfont 1)\, \texttt{value `val' is not allowed}]\hfill(error)\\
+%The value that has been submitted to a key macro is not allowed.
+%This error can be generated by either a choice or a boolean key.
+%\item[\normalfont 2)\, \texttt{`name' undefined in families `fams'}]\hfill(error)\\
+%The key |name| is not defined in the families in |fams|. Probably
+%you mistyped |name|.
+%\item[\normalfont 3)\, \texttt{no key specified for value `val'}]\hfill(error)\\
+%\pf{xkeyval} found a value without a key, for instance something
+%like |=value|, when setting keys.
+%\item[\normalfont 4)\, \texttt{no value recorded for key `name'}]\hfill(error)\\
+%You have used a pointer to a key for which no value has been saved
+%previously.
+%\item[\normalfont 5)\, \texttt{back linking pointers; pointer replacement canceled}]\hfill(error)\\
+%You were back linking pointers. Further pointer replacements are canceled
+%to avoid getting into an infinite loop. See section~\ref{sec:usevalue}.
+%\item[\normalfont 6)\, \texttt{no value specified for key `name'}]\hfill(error)\\
+%You have used the key `name' without specifying any value for it
+%(namely, |\setkeys{fam}{name}| and the key does not have a default
+%value. Notice that |\setkeys{fam}{name=}| submits the empty value to
+%the key macro and that this is considered a legal value.
+%\item[\normalfont 7)\, \label{mess:2}\texttt{key `name' has been disabled}]\hfill(warning)\\
+%The key that you try to set has been disabled and cannot be used anymore.
+%\item[\normalfont 8)\, \texttt{`XKV' prefix is not allowed}]\hfill(error)\\
+%You were trying to use the |XKV| prefix when defining or setting
+%keys. This error can be caused by any \pf{xkeyval} macro having an
+%optional prefix argument.
+%\item[\normalfont 9)\, \texttt{key `name' undefined}]\hfill(error)\\
+%This error message is caused by trying to disable a key that does not
+%exist. See section~\ref{sec:disable}.
+%\item[\normalfont 10)\, \texttt{no save keys defined for `pre@fam@'}]\hfill(error)\\
+%You are trying to delete or undefine save keys that have not been defined yet.
+%See section~\ref{sec:savevalue}.
+%\item[\normalfont 11)\, \texttt{no presets defined for `pre@fam@'}]\hfill(error)\\
+%You are trying to delete or undefine presets that have not been defined yet.
+%See section~\ref{sec:preset}.
+%\item[\normalfont 12)\, \texttt{xkeyval loaded before \cs{documentclass}}]\hfill(error)\\
+%Load \pf{xkeyval} after |\documentclass| (or in the class that is
+%the document class). See section~\ref{sec:options}.
+%\end{description}
+%
+%\section{Category codes}\label{sec:catcodes}
+%Some packages change the catcode of the equality sign and the comma.
+%This is a problem for \pf{keyval} as it then does not recognize
+%these characters anymore and cannot parse the input. This problem
+%can play up on the background. Consider for instance the following
+%example and note that the \pf{graphicx} package is using \pf{keyval}
+%and that Turkish \pf{babel} will activate the equality sign for
+%shorthand notation.
+%\begin{example}
+% \documentclass{article}
+% \usepackage{graphicx}
+% \usepackage[turkish]{babel}
+% \begin{document}
+% \includegraphics[scale=.5]{rose.eps}
+% \end{document}
+%\end{example}
+%The \pf{babel} package provides syntax to temporarily reset the
+%catcode of the equality sign and switch shorthand back on after
+%using \pf{keyval} (in the |\includegraphics| command), namely
+%|\shorthandoff{=}| and |\shorthandon{=}|. But having to do this
+%every time \pf{keyval} is invoked is quite cumbersome. Besides that,
+%it might not always be clear to the user what the problem is and
+%what the solution.
+%
+%For these reasons, \pf{xkeyval} performs several actions with user
+%input before trying to parse it.\footnote{Notice that temporarily
+%resetting catcodes before reading the input to \cs{setkeys} won't
+%suffice, as it will not help solving problems when input has been
+%read before and has been stored in a token register or a macro.}
+%First of all, it performs a check whether the characters |=| and |,|
+%appear in the input with unexpected catcodes. If so, the
+%|\@selective@sanitize| macro is used to sanitize these characters
+%only in the top level. This means that characters inside (a)
+%group(s), |{ }|, will not be sanitized. For instance, when using
+%Turkish \pf{babel}, it is possible to use |=| shorthand notation
+%even in the value of a key, as long as this value is inside a group.
+%\begin{example}
+% \documentclass{article}
+% \usepackage{graphicx}
+% \usepackage[turkish]{babel}
+% \usepackage{xkeyval}
+% \makeatletter
+% \define@key{fam}{key}{#1}
+% \begin{document}
+% \includegraphics[scale=.5]{rose.eps}
+% \setkeys{fam}{key={some =text}}
+% \end{document}
+%\end{example}
+%In the example above, the |\includegraphics| command does work.
+%Further, the first equality sign in the |\setkeys| command will be
+%sanitized, but the second one will be left untouched and will be
+%typeset as \pf{babel} shorthand notation.
+%
+%The commands |\savekeys| and |\disable@keys| are protected against
+%catcode changes of the comma. The commands |\setkeys| and
+%|\presetkeys| are protected against catcode changes of the comma and
+%the equality sign. Note that \LaTeX\ option macros (see
+%section~\ref{sec:options}) are not protected as \LaTeX\ does not
+%protect them either.
+%
+%\section{Known issues}\label{sec:issues}
+%This package redefines \pf{keyval}'s |\define@key| and |\setkeys|.
+%This is risky in general. However, since \pf{xkeyval} extends the
+%possibilities of these commands while still allowing for the
+%\pf{keyval} syntax and use, there should be no problems for packages
+%using these commands after loading \pf{xkeyval}. The package
+%prevents \pf{keyval} to be loaded afterwards to avoid these commands
+%from being redefined again into the simpler versions. For packages
+%using internals of \pf{keyval}, like |\KV@@sp@def|, |\KV@do| and
+%|\KV@errx|, these are provided separately in |keyval.tex|.
+%
+%The advantage of redefining these commands instead of making new
+%commands is that it is much easier for package authors to start
+%using \pf{xkeyval} instead of \pf{keyval}. Further, it eliminates
+%the confusion of having multiple commands doing similar things.
+%
+%A potential problem lies in other packages that redefine either
+%|\define@key| or |\setkeys| or both. Hence particular care has been
+%spend to check packages for this. Only one package has been found to
+%do this, namely \pf{pst-key}. This package implements a custom
+%version of |\setkeys| which is specialized to set \pf{PSTricks}
+%\cite{PSTricksWeb,PSTricks} keys of the form |\psset@somekey|.
+%\pf{xkeyval} also provides the means to set these kind of keys (see
+%page~\pageref{page:pstricks}) and work is going on to convert
+%\pf{PSTricks} packages to be using a specialization of \pf{xkeyval}
+%instead of \pf{pst-key}. This specialization is available in the
+%\pf{pst-xkey} package, which is distributed with the \pf{xkeyval}
+%bundle and is described in section~\ref{sec:pst-xkey}. However, since
+%a lot of authors are involved and since it requires a change of
+%policy, the conversion of \pf{PSTricks} packages might take some
+%time. Hence, at the moment of writing, \pf{xkeyval} will conflict
+%with \pf{pst-key} and the \pf{PSTricks} packages using \pf{pst-key},
+%which are \pf{pst-circ}, \pf{pst-eucl}, \pf{pst-fr3d}, \pf{pst-geo},
+%\pf{pst-gr3d}, \pf{pst-labo}, \pf{pst-lens}, \pf{pst-ob3d},
+%\pf{pst-optic}, \pf{pst-osci}, \pf{pst-poly}, \pf{pst-stru},
+%\pf{pst-uml} and \pf{pst-vue3d}.
+%
+%Have a look at the \pf{PSTricks} website \cite{PSTricksWeb} to find
+%out if the package that you want to use has been converted already.
+%If not, load an already converted package (like \pf{pstricks-add})
+%after loading the old package to make them work.
+%
+%\section{Additional packages}\label{sec:additional}
+%\subsection{\pf{xkvview}}\label{sec:view}
+%The \pf{xkeyval} bundle includes a viewer utility, called
+%\pf{xkvview},\footnote{The \pf{xkvview} package is contained in the
+%file \texttt{xkvview.sty}.} which keeps track of the keys that are
+%defined. This utility is intended for package programmers who want
+%to have an overview of the keys defined in their package(s). All
+%keys defined after loading the package will be recorded in a database.
+%It provides the following commands to display (part of) the database.
+%\begin{command}
+% `\cs{xkvview}\marg{options}'
+%\end{command}
+%\DescribeMacro{\xkvview}
+%When \meta{options} is empty, the entire database will be typeset in
+%a table created with the \pf{longtable} package. The columns will,
+%respectively, contain the key name, the prefix, the family, the type
+%(|ordinary|, |command|, |choice| or |boolean|) and the presence of a
+%default value for every key defined after loading \pf{xkvview}.
+%
+%\DescribeOptions{prefix,family,type,default}
+%There are several options to control the output of this command. This
+%set of options can be used to set up criteria for the keys that
+%should be displayed. If a key does not satisfy one or more of them,
+%it won't be included in the table. For instance, the following example
+%will display all keys with family |fama|, that do not have a
+%default value. Notice that \pf{xkvview} codes `no default value'
+%with |[none]|.
+%\begin{example}
+% \documentclass{article}
+% \usepackage{xkvview}
+% \makeatletter
+% \define@key{fama}{keya}[default]{}
+% \define@cmdkey{fama}{keyb}{}
+% \define@choicekey{famb}{keyc}{a,b}{}
+% \define@boolkey{famb}{keyd}{}
+% \makeatother
+% \begin{document}
+% \xkvview{family=fama,default=[none]}
+% \end{document}
+%\end{example}
+%In the following examples in this section, the same preamble will be
+%used, but will not be displayed explicitly in the examples.
+%
+%\DescribeOption{columns}
+%One can select the columns that should be included in the table using
+%the |columns| option. The following example includes the columns |prefix|
+%and |family| in the table (additional to the key name column).
+%\begin{example}
+% \xkvview{columns={prefix,family}}
+%\end{example}
+%The remaining columns are called |type| and |default|.
+%
+%\DescribeOption{vlabels}
+%If you want to refer to an option, |\xkvview| can automatically generate
+%labels using the scheme \meta{prefix}|-|\meta{family}|-|\meta{keyname}.
+%Here is an example.
+%\begin{example}
+% \xkvview{vlabels=true}
+% Find more information about the keya
+% option on page~\pageref{KV-fama-keya}.
+%\end{example}
+%
+%\DescribeOptions{file,wcolsep,weol}
+%The package can also write (part of) the database to a file. The
+%selection of the information happens in the same way as discussed
+%above. When specifying a filename with the option |file|, the body
+%of the table that is displayed, will also be written to this file.
+%Entries will be separated by |wcolsep| which is |&| by default and
+%every row will be concluded by |weol| which is |\\| by default. The
+%output in the file can then be used as basis for a custom table, for
+%instance in package documentation. The following displays a table in
+%the dvi and also writes the body to |out.tex|.
+%\begin{example}
+% \xkvview{file=out}
+%\end{example}
+%|out.tex| contains
+%\begin{example}
+% keya&KV&fama&ordinary&default\\
+% keyb&KV&fama&command&[none]\\
+% keyc&KV&famb&choice&[none]\\
+% keyd&KV&famb&boolean&[none]\\
+%\end{example}
+%
+%The following example generates a table with entries separated by a
+%space and no end-of-line content.
+%\begin{example}
+% \xkvview{file=out,wcolsep=\space,weol=}
+%\end{example}
+%Now |out.tex| contains
+%\begin{example}
+% keya KV fama ordinary default
+% keyb KV fama command [none]
+% keyc KV famb choice [none]
+% keyd KV famb boolean [none]
+%\end{example}
+%
+%\DescribeOption{wlabels}
+%When post-processing the table generated in this way, one might want
+%to refer to entries again as well. When setting |wlabels| to true,
+%the labels with names \meta{prefix}|-|\meta{family}|-|\meta{keyname}
+%will be in the output file. The following
+%\begin{example}
+% \xkvview{file=out,wlabels=true}
+%\end{example}
+%will result in the following content in |out.tex|
+%\begin{example}
+% keya&KV&fama&ordinary&default\label{KV-fama-keya}\\
+% keyb&KV&fama&command&[none]\label{KV-fama-keyb}\\
+% keyc&KV&famb&choice&[none]\label{KV-famb-keyc}\\
+% keyd&KV&famb&boolean&[none]\label{KV-famb-keyd}\\
+%\end{example}
+%
+%\DescribeOption{view}
+%Finally, when you only want to generate a file and no output to the
+%dvi, set the |view| option to false.
+%\begin{example}
+% \xkvview{file=out,view=false}
+%\end{example}
+%This example only generate |out.tex| and does not put a table in the
+%dvi.
+%
+%\subsection{\pf{xkvltxp}}\label{sec:macrooptions}
+%The package and class option system of \LaTeX\ contained in the
+%kernel performs some expansions while processing options. This
+%prevents doing for instance
+%\begin{example}
+% \documentclass[title=My title,author=\textsc{Me}]{myclass}
+%\end{example}
+%given that |myclass| uses \pf{xkeyval} and defines the options |title|
+%and |author|.
+%
+%This problem can be overcome by redefining certain kernel commands.
+%These redefinitions are contained in the \pf{xkvltxp}
+%package.\footnote{The \pf{xkvltxp} package consists of the file
+%\texttt{xkvltxp.sty}.} If you want to allow the user of your class
+%to be able to specify expandable macros in the package options, the
+%user will have to do |\RequirePackage{xkvltxp}| on the first line of
+%the \LaTeX\ file. If you want to offer this functionality in a
+%package, the user can use the package in the ordinary way with
+%|\usepackage{xkvltxp}|. This package then has to be loaded before
+%loading the package which will use this functionality. A description
+%of the patch can be found in the source code documentation.
+%
+%The examples below summarize this information. The first example
+%shows the case in which we want to allow for macros in the
+%|\documentclass| command.
+%\begin{example}
+% \RequirePackage{xkvltxp}
+% \documentclass[title=My title,author=\textsc{Me}]{myclass}
+% \begin{document}
+% \end{document}
+%\end{example}
+%
+%The second example shows the case in which we want to allow for
+%macros in a |\usepackage| command.
+%\begin{example}
+% \documentclass{article}
+% \usepackage{xkvltxp}
+% \usepackage[footer=page~\thepage.]{mypack}
+% \begin{document}
+% \end{document}
+%\end{example}
+%
+%Any package or class using \pf{xkeyval} and \pf{xkvltxp} to process
+%options can take options that contain macros in their value without
+%expanding them prematurely. However, you can of course not use
+%macros in options which are not of the |key=value| form since they
+%might in the end be passed on to or copied by a package which is not
+%using \pf{xkeyval} to process options, which will then produce
+%errors. Options of the |key=value| form will be deleted from
+%|\@classoptionslist| (see section~\ref{sec:options}) and form no
+%threat for packages loaded later on. Finally, make sure not to pass
+%options of the |key=value| form to packages not using \pf{xkeyval}
+%to process options since they cannot process them. For examples see
+%section~\ref{sec:sande}.
+%
+%\subsection{\pf{pst-xkey}}\label{sec:pst-xkey}
+%The \pf{pst-xkey} package\footnote{The \pf{pst-xkey} package
+%consists of the files \texttt{pst-xkey.tex} and
+%\texttt{pst-xkey.sty}. To load \pf{pst-xkey} \TeX\ users do
+%\cs{input pst-xkey}, \LaTeX\ users do
+%\cs{RequirePackage\{pst-xkey\}} or \cs{usepackage\{pst-xkey\}}.}
+%implements a specialized version of the options system of
+%\pf{xkeyval} designed for \pf{PSTricks} \cite{PSTricksWeb,PSTricks}.
+%This system gives additional freedom to \pf{PSTricks} package
+%authors since they won't have to worry anymore about potentially
+%redefining keys of one of the many other \pf{PSTricks} packages. The
+%command |\psset| is redefined to set keys in multiple families.
+%Reading the documentation of the \pf{xkeyval} package (especially
+%section~\ref{sec:issues}) first is recommended.
+%
+%Keys defined in the original distribution of \pf{PSTricks} have the
+%macro structure |\psset@somekey| (where |psset| is literal). These
+%can be (re)defined by
+%\begin{example}
+% \define@key[psset]{}{somekey}{function}
+%\end{example}
+%Notice especially that these keys are located in the so-called
+%`empty family'. For more information about |\define@key| and friends,
+%see section~\ref{sec:define}.
+%
+%When writing a \pf{PSTricks} package, let's say \pf{pst-new}, you
+%should locate keys in a family which contains the name of your
+%package. If you only need one family, you should define keys using
+%\begin{example}
+% \define@key[psset]{pst-new}{somekey}{function}
+%\end{example}
+%If you want to use multiple families in your package, you can do
+%\begin{example}
+% \define@key[psset]{pst-new-a}{somekey}{function}
+% \define@key[psset]{pst-new-b}{anotherkey}{function}
+%\end{example}
+%
+%\DescribeMacros{\pst@addfams,\pst@famlist}
+%It is important that you add all of the families that you use in
+%your package to the list in |\pst@famlist|.
+%This list of families will be used by |\psset| to scan for keys to
+%set user input. You can add your families to the list using
+%\begin{command}
+% `\cs{pst@addfams}\marg{families}'
+%\end{command}
+%For instance
+%\begin{example}
+% \pst@addfams{pst-new}
+%\end{example}
+%or
+%\begin{example}
+% \pst@addfams{pst-new-a,pst-new-b}
+%\end{example}
+%
+%Only one command is needed to set \pf{PSTricks} keys.
+%\begin{command}
+% `\cs{psset}\oarg{families}\marg{keys}'
+%\end{command}
+%\DescribeMacro{\psset}
+%This command will set \meta{keys} in \meta{families} using
+%|\setkeys+| (see section~\ref{sec:setkeys}). When \meta{families} is
+%not specified, it will set \meta{keys} in all families in
+%|\pst@famlist| (which includes the empty family for original
+%\pf{PSTricks} keys).
+%\begin{example}
+% \psset{somekey=red,anotherkey}
+% \psset[pst-new-b]{anotherkey=green}
+%\end{example}
+%
+%\section{Examples and documentation}\label{sec:sande}
+%To generate the package and example files from the source, find the
+%source of this package, the file |xkeyval.dtx|, in your local \TeX\
+%installation or on CTAN and run it with \LaTeX.
+%\begin{example}
+% latex xkeyval.dtx
+%\end{example}
+%This will generate the package files (|xkeyval.tex|, |xkeyval.sty|,
+%|xkvltxp.sty|, |keyval.tex|, |xkvtxhdr.tex| |xkvview.sty|,
+%|pst-xkey.tex| and |pst-xkey.sty|) and the example files.
+%
+%The file |xkvex1.tex| provides an example for \TeX\ users for the
+%macros described in sections~\ref{sec:define},
+%\ref{sec:setkeys}, \ref{sec:pointers} and \ref{sec:preset}. The file
+%|xkvex2.tex| provides an example for \LaTeX\ users for the same
+%macros. The files |xkvex3.tex|, |xkveca.cls|, |xkvecb.cls|,
+%|xkvesa.sty|, |xkvesb.sty| and |xkvesc.sty| together form an example
+%for the macros described in section~\ref{sec:options}. The set of
+%files |xkvex4.tex|, |xkveca.cls|, |xkvecb.cls|, |xkvesa.sty|,
+%|xkvesb.sty| and |xkvesc.sty| provides an example for
+%sections~\ref{sec:options} and~\ref{sec:macrooptions}. These files
+%also demonstrate the possibilities of interaction between packages
+%or classes not using \pf{xkeyval} and packages or classes that do
+%use \pf{xkeyval} to set options.
+%
+%To (re)generate this documentation, perform the following steps.
+%\begin{example}
+% latex xkeyval.dtx
+% latex xkeyval.dtx
+% bibtex xkeyval
+% makeindex -s gglo.ist -o xkeyval.gls xkeyval.glo
+% makeindex -s gind.ist -o xkeyval.ind xkeyval.idx
+% latex xkeyval.dtx
+% latex xkeyval.dtx
+%\end{example}
+%
+% \StopEventually{}
+%
+% \section{Implementation}\label{sec:imple}
+% \subsection{\texttt{xkeyval.tex}}
+% Avoid loading |xkeyval.tex| twice.
+% \begin{macrocode}
+%<*xkvtex>
+\csname XKeyValLoaded\endcsname
+\let\XKeyValLoaded\endinput
+% \end{macrocode}
+% Adjust some catcodes to define internal macros.
+% \begin{macrocode}
+\edef\XKVcatcodes{%
+ \catcode`\noexpand\@\the\catcode`\@\relax
+ \catcode`\noexpand\=\the\catcode`\=\relax
+ \catcode`\noexpand\,\the\catcode`\,\relax
+ \catcode`\noexpand\:\the\catcode`\:\relax
+ \let\noexpand\XKVcatcodes\relax
+}
+\catcode`\@11\relax
+\catcode`\=12\relax
+\catcode`\,12\relax
+\catcode`\:12\relax
+% \end{macrocode}
+% Initializations. This package uses a private token to avoid
+% conflicts with other packages that use \LaTeX\ scratch token registers
+% in key macro definitions (for instance, \pf{graphicx}, keys angle
+% and scale).
+% \begin{macrocode}
+\newtoks\XKV@toks
+\newcount\XKV@depth
+\newif\ifXKV@st
+\newif\ifXKV@sg
+\newif\ifXKV@pl
+\newif\ifXKV@knf
+\newif\ifXKV@rkv
+\newif\ifXKV@inpox
+\newif\ifXKV@preset
+\let\XKV@rm\@empty
+% \end{macrocode}
+% Load \LaTeX\ primitives if necessary and provide information.
+% \begin{macrocode}
+\ifx\ProvidesFile\@undefined
+ \message{2005/08/12 v2.5d key=value parser (HA)}
+ \input xkvtxhdr
+\else
+ \ProvidesFile{xkeyval.tex}[2005/08/12 v2.5d key=value parser (HA)]
+ \@addtofilelist{xkeyval.tex}
+\fi
+% \end{macrocode}
+% \begin{macro}{\@firstoftwo}
+% \begin{macro}{\@secondoftwo}
+% Two utility macros from the |latex.ltx| needed for executing
+% |\XKV@ifundefined| in the sequel.
+% \begin{macrocode}
+\long\def\@firstoftwo#1#2{#1}
+\long\def\@secondoftwo#1#2{#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@afterfi}
+% \begin{macro}{\XKV@afterelsefi}
+% Two utility macros to move execution of content of a conditional
+% branch after the |\fi|. This avoids nesting conditional structures
+% too deep.
+% \begin{macrocode}
+\long\def\XKV@afterfi#1\fi{\fi#1}
+\long\def\XKV@afterelsefi#1\else#2\fi{\fi#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@ifundefined}
+% \changes{v1.8d}{2005/01/02}{Simplified definition by using \cs{XKV@afterelsefi}}
+% \changes{v2.0}{2005/01/30}{Made none \eTeX\ version not leave \cs{relax}}
+% \marg{csname}\marg{undefined}\marg{defined}\\
+% Executes \meta{undefined} if the control sequence with name \meta{csname}
+% is undefined, else it executes \meta{defined}. This macro uses
+% \eTeX\ if possible to avoid filling \TeX's hash when checking
+% control sequences like key macros in the rest of the package.
+% The use of |\XKV@afterelsefi| is necessary here to avoid \TeX\ picking up the
+% second |\fi| as end of the main conditional when |\ifcsname| is
+% undefined. For |\XKV@afterelsefi| this |\fi| is hidden in the
+% group used to define |\XKV@ifundefined| in branch of the case that
+% |\ifcsname| is defined. Notice the following. Both versions of the
+% macro leave the tested control sequence undefined. However, the
+% first version will execute \meta{undefined} if the control sequence
+% is undefined or |\relax|, whereas the second version will only
+% execute \meta{undefined} if the control sequence is undefined. This
+% is no problem for the applications in this package.
+% \begin{macrocode}
+\ifx\ifcsname\@undefined\XKV@afterelsefi
+ \def\XKV@ifundefined#1{%
+ \begingroup\expandafter\expandafter\expandafter\endgroup
+ \expandafter\ifx\csname#1\endcsname\relax
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ }
+\else
+ \def\XKV@ifundefined#1{%
+ \ifcsname#1\endcsname
+ \expandafter\@secondoftwo
+ \else
+ \expandafter\@firstoftwo
+ \fi
+ }
+\fi
+% \end{macrocode}
+% \end{macro}
+% Check whether \pf{keyval} has been loaded and if not, load
+% \pf{keyval} primitives and prevent \pf{keyval} from being loaded
+% after \pf{xkeyval}.
+% \begin{macrocode}
+\XKV@ifundefined{ver@keyval.sty}{
+ \input keyval
+ \expandafter\def\csname ver@keyval.sty\endcsname{1999/03/16}
+}{}
+% \end{macrocode}
+% \begin{macro}{\@ifnextcharacter}
+% \changes{v1.4}{2004/08/24}{Added robust next character check}
+% \begin{macro}{\@ifncharacter}
+% Check the next character independently of its catcode. This will be
+% used to safely perform |\@ifnextcharacter+| and
+% |\@ifnextcharacter*|. This avoids errors in case any other package
+% changes the catcode of these characters.\\ Contributed by Donald
+% Arseneau.
+% \begin{macrocode}
+\long\def\@ifnextcharacter#1#2#3{%
+ \@ifnextchar\bgroup
+ {\@ifnextchar{#1}{#2}{#3}}%
+ {\@ifncharacter{#1}{#2}{#3}}%
+}
+\long\def\@ifncharacter#1#2#3#4{%
+ \if\string#1\string#4%
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ {#2}{#3}#4%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@for@n}
+% \marg{list}\meta{cmd}\marg{function}\\
+% Fast for-loop. \meta{list} is not expanded. Entries of \meta{list}
+% will be stored in \meta{cmd} and at every iteration \meta{function}
+% is executed.\\
+% Contributed by Morten H\o gholm.
+% \begin{macrocode}
+\long\def\XKV@for@n#1#2#3{%
+ \def#2{#1}%
+ \ifx#2\@empty
+ \XKV@for@break
+ \else
+ \expandafter\XKV@f@r
+ \fi
+ #2{#3}#1,\@nil,%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@f@r}
+% \meta{cmd}\marg{function}\meta{entry}|,|\\
+% Looping macro.
+% \begin{macrocode}
+\long\def\XKV@f@r#1#2#3,{%
+ \def#1{#3}%
+ \ifx#1\@nnil
+ \expandafter\@gobbletwo
+ \else
+ #2\expandafter\XKV@f@r
+ \fi
+ #1{#2}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@for@break}
+% \meta{text}|\@nil,|\\
+% Macro to stop the for-loop.
+% \begin{macrocode}
+\long\def\XKV@for@break #1\@nil,{\fi}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@for@o}
+% \meta{listcmd}\meta{cmd}\marg{function}\\
+% \meta{listcmd} is expanded once before starting the loop.
+% \begin{macrocode}
+\long\def\XKV@for@o#1{\expandafter\XKV@for@n\expandafter{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@for@en}
+% \marg{list}\meta{cmd}\marg{function}\\
+% As |\XKV@for@n|, but this macro will execute \meta{function} also
+% when \meta{list} is empty. This is done to support packages that use the `empty
+% family', like \pf{PSTricks}.
+% \begin{macrocode}
+\long\def\XKV@for@en#1#2#3{\XKV@f@r#2{#3}#1,\@nil,}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@for@eo}
+% \meta{listcmd}\meta{cmd}\marg{function}\\
+% As |\XKV@for@o|, but this macro will execute \meta{function} also
+% when \meta{listcmd} is empty.
+% \begin{macrocode}
+\long\def\XKV@for@eo#1#2#3{%
+ \def#2{\XKV@f@r#2{#3}}\expandafter#2#1,\@nil,%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@whilist}
+% \meta{listcmd}\meta{cmd}\meta{if}|\fi|\marg{function}\\
+% \changes{v1.5}{2004/09/27}{Changed behavior}
+% \meta{listcmd} is expanded once. Execution of \meta{function} stops when either
+% the list has ran out of elements or \meta{if} is not true anymore.
+% When using |\iftrue| for \meta{if}, the execution of the macro is the
+% same as that of |\XKV@for@o|, but contains an additional check at every
+% iteration and is
+% hence less efficient than |\XKV@for@o| in that situation.
+% \begin{macrocode}
+\long\def\XKV@whilist#1#2#3\fi#4{%
+% \end{macrocode}
+% Check whether the condition is true and start iteration.
+% \begin{macrocode}
+ #3\expandafter\XKV@wh@list#1,\@nil,\@nil\@@#2#3\fi{#4}{}\fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@wh@list}
+% \changes{v1.6}{2004/10/05}{Added missing \%}
+% \changes{v1.9}{2005/01/16}{Made running command contain last used list entry at exit}
+% \changes{v2.4}{2005/03/31}{Avoid using grouping}
+% \meta{entry}|,|\meta{text}|\@@|\meta{cmd}\meta{if}|\fi|\marg{function}\marg{previous}\\
+% Performs iteration and checks extra condition. This macro is not
+% optimized for the case that the list contains a single element. At
+% the end of every iteration, the current \meta{entry} will be stored
+% in \meta{previous} for the next iteration. The previous entry is
+% necessary when stepping out of the loop.
+% \begin{macrocode}
+\long\def\XKV@wh@list#1,#2\@@#3#4\fi#5#6{%
+% \end{macrocode}
+% Define the running \meta{cmd}.
+% \begin{macrocode}
+ \def#3{#1}%
+% \end{macrocode}
+% If we find the end of the list, stop.
+% \begin{macrocode}
+ \ifx#3\@nnil
+ \def#3{#6}\expandafter\XKV@wh@l@st
+ \else
+% \end{macrocode}
+% If the condition is met, execute \meta{function} and continue.
+% Otherwise, define the running command to be the previous entry
+% (which inflicted the condition becoming false) and stop.
+% \begin{macrocode}
+ #4%
+ #5\expandafter\expandafter\expandafter\XKV@wh@list
+ \else
+ \def#3{#6}\expandafter\expandafter\expandafter\XKV@wh@l@st
+ \fi
+ \fi
+ #2\@@#3#4\fi{#5}{#1}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@wh@l@st}
+% \meta{text}|\@@|\meta{cmd}\meta{if}|\fi|\marg{function}\marg{previous}\\
+% Macro to gobble remaining input.
+% \begin{macrocode}
+\long\def\XKV@wh@l@st#1\@@#2#3\fi#4#5{}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@addtomacro@n}
+% \meta{macro}\marg{content}\\
+% Adds \meta{content} to \meta{macro} without expanding it.
+% \begin{macrocode}
+\def\XKV@addtomacro@n#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@addtomacro@o}
+% \meta{macro}\marg{content}\\
+% Adds \meta{content} to \meta{macro} after expanding the first token
+% of \meta{content} once. Often used to add the content of a macro
+% to another macro.
+% \begin{macrocode}
+\def\XKV@addtomacro@o#1#2{%
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter#1\expandafter
+ \expandafter\expandafter{\expandafter#1#2}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@addtolist@n}
+% \meta{cmd}\marg{content}\\
+% \changes{v1.8 }{2004/12/13}{Changed to respect groups}
+% \changes{v2.0}{2005/01/30}{Simplified}
+% Adds \meta{content} to the list in \meta{cmd} without expanding \meta{content}.
+% Notice that it is assumed that \meta{cmd} is not undefined.
+% \begin{macrocode}
+\def\XKV@addtolist@n#1#2{%
+ \ifx#1\@empty
+ \XKV@addtomacro@n#1{#2}%
+ \else
+ \XKV@addtomacro@n#1{,#2}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@addtolist@o}
+% \meta{cmd}\marg{content}\\
+% \changes{v2.0}{2005/01/30}{Simplified}
+% Adds \meta{content} to the list in \meta{cmd} after expanding the
+% first token in \meta{content} once.
+% \begin{macrocode}
+\def\XKV@addtolist@o#1#2{%
+ \ifx#1\@empty
+ \XKV@addtomacro@o#1#2%
+ \else
+ \XKV@addtomacro@o#1{\expandafter,#2}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@addtolist@x}
+% \meta{cmd}\marg{content}\\
+% Adds \meta{content} to the list in \meta{cmd} after a full expansion
+% of both \meta{cmd} and \meta{content}.
+% \begin{macrocode}
+\def\XKV@addtolist@x#1#2{\edef#1{#1\ifx#1\@empty\else,\fi#2}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@selective@sanitize}
+% \begin{macro}{\@s@lective@sanitize}
+% \changes{v2.5a}{2005/05/31}{Added missing `\%'}
+% \oarg{level}\marg{character string}\marg{cmd}\\
+% Converts selected characters, given by \meta{character string},
+% within the first-level expansion of \meta{cmd} to category code~12,
+% leaving all other tokens (including grouping braces) untouched.
+% Thus, macros inside \meta{cmd} do not lose their function, as it is
+% the case with |\@onelevel@sanitize|.
+% The resulting token list is again saved in \meta{cmd}.\\
+% Example: |\def\cs{ ^{\fi}~}| and |\@selective@sanitize{!^}\cs| will
+% change the catcode of `|^|' to \emph{other}
+% within |\cs|, while |\fi| and `|~|' will remain unchanged.
+% As the example shows, unbalanced conditionals are allowed.\\
+% Remarks: \meta{cmd} should not contain the control sequence |\bgroup|;
+% however, |\csname| |bgroup\endcsname| and |\egroup| are possible.
+% The optional \meta{level} command controls up to which nesting
+% level sanitizing takes place inside groups; |0| will only sanitize
+% characters in the top level, |1| will also sanitize within the first
+% level of braces (but not in the second), etc.
+% The default value is |10000|.
+% \begin{macrocode}
+\def\@selective@sanitize{\@testopt\@s@lective@sanitize\@M}
+\def\@s@lective@sanitize[#1]#2#3{%
+ \begingroup
+ \count@#1\relax\advance\count@\@ne
+ \XKV@toks\expandafter{#3}%
+ \def#3{#2}\@onelevel@sanitize#3%
+ \edef#3{{#3}{\the\XKV@toks}}%
+ \expandafter\@s@l@ctive@sanitize\expandafter#3#3%
+ \expandafter\endgroup\expandafter\def\expandafter#3\expandafter{#3}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\@s@l@ctive@sanitize}
+% \changes{v1.8 }{2004/12/13}{Bug fixed, added level control}
+% \marg{cmd}\marg{sanitized character string}\marg{token list}\\
+% Performs the main work.
+% Here, the characters in \meta{sanitized character string} are already
+% converted to catcode~12, \meta{token list} is the first-level expansion
+% of the original contents of \meta{cmd}.
+% The macro basically steps through the \meta{token list}, inspecting
+% each single token to decide whether it has to be sanitized or passed
+% to the result list.
+% Special care has to be taken to detect spaces, grouping characters
+% and conditionals (the latter may disturb other expressions).
+% However, it is easier and more efficient to look for \TeX{}
+% primitives in general -- which are characterized by a |\meaning|
+% that starts with a backslash -- than to test whether a token equals
+% specifically |\if|, |\else|, |\fi|, etc.
+% Note that |\@s@l@ctive@sanitize| is being called recursively if
+% \meta{token list} contains grouping braces.
+% \begin{macrocode}
+\def\@s@l@ctive@sanitize#1#2#3{%
+ \def\@i{\futurelet\@@tok\@ii}%
+ \def\@ii{%
+ \expandafter\@iii\meaning\@@tok\relax
+ \ifx\@@tok\@s@l@ctive@sanitize
+ \let\@@cmd\@gobble
+ \else
+ \ifx\@@tok\@sptoken
+ \XKV@toks\expandafter{#1}\edef#1{\the\XKV@toks\space}%
+ \def\@@cmd{\afterassignment\@i\let\@@tok= }%
+ \else
+ \let\@@cmd\@iv
+ \fi
+ \fi
+ \@@cmd
+ }%
+ \def\@iii##1##2\relax{\if##1\@backslashchar\let\@@tok\relax\fi}%
+ \def\@iv##1{%
+ \toks@\expandafter{#1}\XKV@toks{##1}%
+ \ifx\@@tok\bgroup
+ \advance\count@\m@ne
+ \ifnum\count@>\z@
+ \begingroup
+ \def#1{\expandafter\@s@l@ctive@sanitize
+ \csname\string#1\endcsname{#2}}%
+ \expandafter#1\expandafter{\the\XKV@toks}%
+ \XKV@toks\expandafter\expandafter\expandafter
+ {\csname\string#1\endcsname}%
+ \edef#1{\noexpand\XKV@toks{\the\XKV@toks}}%
+ \expandafter\endgroup#1%
+ \fi
+ \edef#1{\the\toks@{\the\XKV@toks}}%
+ \advance\count@\@ne
+ \let\@@cmd\@i
+ \else
+ \edef#1{\expandafter\string\the\XKV@toks}%
+ \expandafter\in@\expandafter{#1}{#2}%
+ \edef#1{\the\toks@\ifin@#1\else
+ \ifx\@@tok\@sptoken\space\else\the\XKV@toks\fi\fi}%
+ \edef\@@cmd{\noexpand\@i\ifx\@@tok\@sptoken\the\XKV@toks\fi}%
+ \fi
+ \@@cmd
+ }%
+ \let#1\@empty\@i#3\@s@l@ctive@sanitize
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@checksanitizea}
+% \marg{content}\meta{cmd}\\
+% Check whether \meta{content}, to be saved to macro \meta{cmd} unexpanded,
+% contains the characters |=| or |,| with wrong catcodes. If so, it sanitizes
+% them before saving \meta{content} to \meta{cmd}.
+% \begin{macrocode}
+\def\XKV@checksanitizea#1#2{%
+ \XKV@ch@cksanitize{#1}#2=%
+ \ifin@\else\XKV@ch@cksanitize{#1}#2,\fi
+ \ifin@\@selective@sanitize[0]{,=}#2\fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@checksanitizeb}
+% \marg{content}\meta{cmd}\\
+% Similar to |\XKV@checksanitizea|, but only checks commas.
+% \begin{macrocode}
+\def\XKV@checksanitizeb#1#2{%
+ \XKV@ch@cksanitize{#1}#2,%
+ \ifin@\@selective@sanitize[0],#2\fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@ch@cksanitize}
+% \changes{v1.8b}{2004/12/22}{Fixed bug for key value \cs{@empty}}
+% \marg{character string}\meta{cmd}\meta{token}\\
+% This macro first checks whether at least one \meta{token} is in \meta{character string}.
+% If that is the case, it checks whether the character has catcode 12.
+% Note that the macro will conclude that the character does not have
+% catcode 12 when it is used inside a group |{}|, but that is not a
+% problem, as we don't expect \meta{token} (namely |,| or |=|) inside
+% a group, unless this group is in a key value. But we won't worry about
+% those characters anyway since the relevant user key macro will have to
+% process that. Further, it is assumed that all occurrences of \meta{token}
+% in \meta{character string} have the same catcode. \meta{cmd} is used
+% as a temporary macro and will contain \meta{character string} at the
+% end of the macro.
+% \begin{macrocode}
+\def\XKV@ch@cksanitize#1#2#3{%
+ \def#2{#1}%
+ \@onelevel@sanitize#2%
+% \end{macrocode}
+% Check whether there is at least one |=| present.
+% \begin{macrocode}
+ \@expandtwoargs\in@#3{#2}%
+ \ifin@
+% \end{macrocode}
+% If so, try to find it. If we can't find it, the character(s) has (or
+% have) the wrong catcode. In that case sanitizing is necessary. This
+% actually occurs, because the input was read by \TeX\
+% before (and for instance stored in a macro or token register).
+% \begin{macrocode}
+ \def#2##1#3##2\@nil{%
+ \def#2{##2}%
+ \ifx#2\@empty\else\in@false\fi
+ }%
+ #2#1#3\@nil
+ \fi
+ \def#2{#1}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@sp@deflist}
+% \changes{v1.8a}{2004/12/20}{Modified to respect the empty family}
+% \meta{cmd}\marg{token list}\\
+% Defines \meta{cmd} as \meta{token list} after removing spaces surrounding
+% elements of the list in \meta{token list}. So, |keya, key b| becomes
+% |keya,key b|. This is used to remove spaces from around elements in
+% a list. Using |\zap@space| for this job, would also remove the
+% spaces inside elements and hence changing key or family names with
+% spaces. This method is slower, but does allow for spaces in key and
+% family names, just as \pf{keyval} did. We need this algorithm at
+% several places to be able to perform |\in@{,key,}{,...,}|, without
+% having to worry about spaces in between commas and key names.
+% \begin{macrocode}
+\def\XKV@sp@deflist#1#2{%
+ \let#1\@empty
+ \XKV@for@n{#2}\XKV@resa{%
+ \expandafter\KV@@sp@def\expandafter\XKV@resa\expandafter{\XKV@resa}%
+ \XKV@addtomacro@o#1{\expandafter,\XKV@resa}%
+ }%
+ \ifx#1\@empty\else
+ \def\XKV@resa,##1\@nil{\def#1{##1}}%
+ \expandafter\XKV@resa#1\@nil
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@merge}
+% \changes{v1.8 }{2004/12/13}{Simplified}
+% \meta{list}\marg{new items}\meta{filter}\\
+% This is a merging macro. For a given new item, the old
+% items are scanned. If an old item key name matches with a new
+% one, the new one will replace the old one. If not, the old one will
+% be appended (and might be overwritten in a following loop). If, at
+% the end of the old item loop the new item has not been used, it
+% will be appended to the end of the list. This macro works irrespective
+% of special syntax. The \meta{filter} is used to filter the key name
+% from the syntax, eg |\global{key}|. All occurrences of a particulary key
+% in the existing list will be overwritten by the new item. This macro
+% is used to make |\savekeys| and |\presetkeys| incremental. The
+% \meta{filter} is |\XKV@getsg| and |\XKV@getkeyname| respectively.
+% \begin{macrocode}
+\def\XKV@merge#1#2#3{%
+ \XKV@checksanitizea{#2}\XKV@tempa
+% \end{macrocode}
+% Start the loop over the new presets. At every iteration, one new preset
+% will be compared with old presets.
+% \begin{macrocode}
+ \XKV@for@o\XKV@tempa\XKV@tempa{%
+ \XKV@pltrue
+% \end{macrocode}
+% Retrieve the key name of the new item at hand.
+% \begin{macrocode}
+ #3\XKV@tempa\XKV@tempb
+% \end{macrocode}
+% Store the (partially updated) old list in a temp macro and empty
+% the original macro.
+% \begin{macrocode}
+ \let\XKV@tempc#1%
+ \let#1\@empty
+% \end{macrocode}
+% Start a loop over the old list.
+% \begin{macrocode}
+ \XKV@for@o\XKV@tempc\XKV@tempc{%
+% \end{macrocode}
+% Retrieve the key name of the old key at hand.
+% \begin{macrocode}
+ #3\XKV@tempc\XKV@tempd
+ \ifx\XKV@tempb\XKV@tempd
+% \end{macrocode}
+% If the key names are equal, append the new item to the list
+% and record that this key should not be added to the end of the
+% presets list.
+% \begin{macrocode}
+ \XKV@plfalse
+ \XKV@addtolist@o#1\XKV@tempa
+ \else
+% \end{macrocode}
+% If the key names are not equal, then just append the current item
+% to the list.
+% \begin{macrocode}
+ \XKV@addtolist@o#1\XKV@tempc
+ \fi
+ }%
+% \end{macrocode}
+% If, after checking the old item, no old item has been overwritten
+% then append the new item to the end of the existing list.
+% \begin{macrocode}
+ \ifXKV@pl\XKV@addtolist@o#1\XKV@tempa\fi
+ }%
+% \end{macrocode}
+% If requested, save the new list globally.
+% \begin{macrocode}
+ \ifXKV@st\global\let#1#1\fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@delete}
+% \meta{list}\marg{delete}\meta{filter}\\
+% Delete entries \meta{delete} by key name from a \meta{list} of presets
+% or save keys using \meta{filter}. For |\delpresetkeys|,
+% this is the macro |\XKV@getkeyname| and for |\delsavekeys|, it is
+% the macro |\XKV@getsg|.
+% \begin{macrocode}
+\def\XKV@delete#1#2#3{%
+% \end{macrocode}
+% Sanitize comma's.
+% \begin{macrocode}
+ \XKV@checksanitizeb{#2}\XKV@tempa
+% \end{macrocode}
+% Copy the current list and make the original empty.
+% \begin{macrocode}
+ \let\XKV@tempb#1%
+ \let#1\@empty
+% \end{macrocode}
+% Run over the current list.
+% \begin{macrocode}
+ \XKV@for@o\XKV@tempb\XKV@tempb{%
+% \end{macrocode}
+% Get the key name to identify the current entry.
+% \begin{macrocode}
+ #3\XKV@tempb\XKV@tempc
+% \end{macrocode}
+% If the current key name is in the list, do not add it anymore.
+% \begin{macrocode}
+ \@expandtwoargs\in@{,\XKV@tempc,}{,\XKV@tempa,}%
+ \ifin@\else\XKV@addtolist@o#1\XKV@tempb\fi
+ }%
+% \end{macrocode}
+% Save globally is necessary.
+% \begin{macrocode}
+ \ifXKV@st\global\let#1#1\fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@warn}
+% \begin{macro}{\XKV@err}
+% \begin{macro}{\KV@err}
+% \begin{macro}{\KV@errx}
+% Warning and error macros. We redefine the \pf{keyval} error macros
+% to use the \pf{xkeyval} ones. This avoids redefining them again when
+% we redefine the |\XKV@warn| and |\XKV@err| macros in |xkeyval.sty|.
+% \begin{macrocode}
+\def\XKV@warn#1{\message{xkeyval warning: #1}}
+\def\XKV@err#1{\errmessage{xkeyval error: #1}}
+\def\KV@errx{\XKV@err}
+\let\KV@err\KV@errx
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@ifstar}
+% \begin{macro}{\XKV@ifplus}
+% Checks whether the following token is a |*| or |+|. Use
+% |\XKV@ifnextchar| to perform the action safely and ignore catcodes.
+% \begin{macrocode}
+\def\XKV@ifstar#1{\@ifnextcharacter*{\@firstoftwo{#1}}}
+\def\XKV@ifplus#1{\@ifnextcharacter+{\@firstoftwo{#1}}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@makepf}
+% \changes{v1.7}{2004/11/25}{Made macro protect internal macros}
+% \marg{prefix}\\
+% This macro creates the prefix, like |prefix@| in |\prefix@family@key|.
+% First it deletes spaces from the input and checks whether it is empty.
+% If not empty, an |@|-sign is added. The use of the |XKV| prefix is
+% forbidden to protect internal macros and special macros like saved
+% key values.
+% \begin{macrocode}
+\def\XKV@makepf#1{%
+ \KV@@sp@def\XKV@prefix{#1}%
+ \def\XKV@resa{XKV}%
+ \ifx\XKV@prefix\XKV@resa
+ \XKV@err{`XKV' prefix is not allowed}%
+ \let\XKV@prefix\@empty
+ \else
+ \edef\XKV@prefix{\ifx\XKV@prefix\@empty\else\XKV@prefix @\fi}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@makehd}
+% \marg{family}\\
+% Creates the header, like |prefix@family@| in |\prefix@family@key|.
+% If \meta{family} is empty, the header reduces to |prefix@|.
+% \begin{macrocode}
+\def\XKV@makehd#1{%
+ \expandafter\KV@@sp@def\expandafter\XKV@header\expandafter{#1}%
+ \edef\XKV@header{%
+ \XKV@prefix\ifx\XKV@header\@empty\else\XKV@header @\fi
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@srstate}
+% \marg{postfix1}\marg{postfix2}\\
+% Macro to save and restore \pf{xkeyval} internals to allow for
+% nesting |\setkeys| commands. It executes a for loop over a set of
+% \pf{xkeyval} internals and does, for instance, |\let\XKV@na@i\XKV@na|
+% to prepare for stepping a level deeper. If \meta{prefix2} is empty,
+% we step a level deeper. If \meta{prefix1} is empty, we go a level up.
+% The non-empty argument is always |@\romannumeral\XKV@depth|. Notice
+% that this also helps to keep changes to boolean settings (for instance
+% by |\XKV@cc*+|) local to the execution of that key.
+% \begin{macrocode}
+\def\XKV@srstate#1#2{%
+ \ifx\@empty#2\@empty\advance\XKV@depth\@ne\fi
+ \XKV@for@n{XKV@prefix,XKV@fams,XKV@na,ifXKV@st,ifXKV@pl,ifXKV@knf}%
+ \XKV@resa{\expandafter\let\csname\XKV@resa#1\expandafter
+ \endcsname\csname\XKV@resa#2\endcsname
+ }%
+ \ifx\@empty#1\@empty\advance\XKV@depth\m@ne\fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@testopta}
+% \begin{macro}{\XKV@t@stopta}
+% \marg{function}\\
+% Tests for the presence of an optional star or plus and executes
+% \meta{function} afterwards.
+% \begin{macrocode}
+\def\XKV@testopta#1{%
+ \XKV@ifstar{\XKV@sttrue\XKV@t@stopta{#1}}%
+ {\XKV@stfalse\XKV@t@stopta{#1}}%
+}
+\def\XKV@t@stopta#1{\XKV@ifplus{\XKV@pltrue#1}{\XKV@plfalse#1}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@testoptb}
+% \begin{macro}{\XKV@t@stoptb}
+% \marg{function}\\
+% First check for an optional prefix. Afterwards, set the \meta{prefix}, set
+% the header, remove spaces from the \meta{family} and execute \meta{function}.
+% \begin{macrocode}
+\def\XKV@testoptb#1{\@testopt{\XKV@t@stoptb#1}{KV}}
+\def\XKV@t@stoptb#1[#2]#3{%
+% \end{macrocode}
+% Set prefix.
+% \begin{macrocode}
+ \XKV@makepf{#2}%
+% \end{macrocode}
+% Set header.
+% \begin{macrocode}
+ \XKV@makehd{#3}%
+% \end{macrocode}
+% Save family name for later use.
+% \begin{macrocode}
+ \KV@@sp@def\XKV@tfam{#3}%
+ #1%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@testoptc}
+% \begin{macro}{\XKV@t@stoptc}
+% \marg{function}\\
+% Test for an optional \meta{prefix}. Then, set the \meta{prefix},
+% sanitize comma's in the list of \meta{families} and remove redundant
+% spaces from this list. Finally, check for optional key names that
+% should not be set and execute \meta{function}.
+% \begin{macrocode}
+\def\XKV@testoptc#1{\@testopt{\XKV@t@stoptc#1}{KV}}
+\def\XKV@t@stoptc#1[#2]#3{%
+ \XKV@makepf{#2}%
+ \XKV@checksanitizeb{#3}\XKV@fams
+ \expandafter\XKV@sp@deflist\expandafter
+ \XKV@fams\expandafter{\XKV@fams}%
+ \@testopt#1{}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@testoptd}
+% \begin{macro}{\XKV@t@stoptd}
+% \marg{function}\\
+% Use |\XKV@testoptb| first to find \meta{prefix} and the
+% \meta{family}. Then check for optional \meta{mp} (`macro prefix').
+% Next eat the \meta{key} name and check for an optional
+% \meta{default} value.
+% \begin{macrocode}
+\def\XKV@testoptd#1#2{%
+ \XKV@testoptb{%
+ \edef\XKV@tempa{#2\XKV@header}%
+ \def\XKV@tempb{\@testopt{\XKV@t@stoptd#1}}%
+ \expandafter\XKV@tempb\expandafter{\XKV@tempa}%
+ }%
+}
+\def\XKV@t@stoptd#1[#2]#3{%
+% \end{macrocode}
+% |\ifXKV@st| gives the presence of an optional default value.
+% \begin{macrocode}
+ \@ifnextchar[{\XKV@sttrue#1{#2}{#3}}{\XKV@stfalse#1{#2}{#3}[]}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@ifcmd}
+% \begin{macro}{\XKV@@ifcmd}
+% \marg{tokens}\marg{macro}\marg{cmd}\marg{yes}\marg{no}\\
+% This macro checks whether the \meta{tokens} contains the macro
+% specification \meta{macro}. If so, the argument to this macro
+% will be saved to \meta{cmd} and \meta{yes} will be executed.
+% Otherwise, the content of \meta{tokens} is saved to \meta{cmd}
+% and \meta{no} is executed. This macro will, for instance, be used
+% to distinguish |key| and |\global{key}| and retrieve |key| in the
+% latter case.
+% \begin{macrocode}
+\def\XKV@ifcmd#1#2#3{%
+ \def\XKV@@ifcmd##1#2##2##3\@nil##4{%
+ \def##4{##2}\ifx##4\@nnil
+ \def##4{##1}\expandafter\@secondoftwo
+ \else
+ \expandafter\@firstoftwo
+ \fi
+ }%
+ \XKV@@ifcmd#1#2{\@nil}\@nil#3%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@getkeyname}
+% \meta{keyvalue}\meta{bin}\\
+% Utility macro to retrieve the key name from \meta{keyvalue} which
+% is of the form |key=value|, |\savevalue{key}=value| or
+% |\gsavevalue{key}=value|, possibly without |value|. |\ifXKV@rkv|
+% will record whether this particular value should be saved.
+% |\ifXKV@sg| will record whether this value should be saved globally
+% or not. The key name will be stored in \meta{bin}.
+% \begin{macrocode}
+\def\XKV@getkeyname#1#2{\expandafter\XKV@g@tkeyname#1=\@nil#2}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@g@tkeyname}
+% \meta{key}|=|\meta{value}|\@nil|\meta{bin}\\
+% Use |\XKV@ifcmd| several times to check the syntax of \meta{value}.
+% Save \meta{key} to \meta{bin}.
+% \begin{macrocode}
+\def\XKV@g@tkeyname#1=#2\@nil#3{%
+ \XKV@ifcmd{#1}\savevalue#3{\XKV@rkvtrue\XKV@sgfalse}{%
+ \XKV@ifcmd{#1}\gsavevalue#3%
+ {\XKV@rkvtrue\XKV@sgtrue}{\XKV@rkvfalse\XKV@sgfalse}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@getsg}
+% \meta{key}\meta{bin}\\
+% Utility macro to check whether |key| or |\global{key}| has been
+% specified in \meta{key}. The key name is saved to \meta{bin}
+% \begin{macrocode}
+\def\XKV@getsg#1#2{%
+ \expandafter\XKV@ifcmd\expandafter{#1}\global#2\XKV@sgtrue\XKV@sgfalse
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@define@default}
+% \marg{key}\marg{default}\\
+% Defines the default value macro for \meta{key} and given |\XKV@header|.
+% \begin{macrocode}
+\def\XKV@define@default#1#2{%
+ \expandafter\def\csname\XKV@header#1@default\expandafter
+ \endcsname\expandafter{\csname\XKV@header#1\endcsname{#2}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\define@key}
+% \changes{v1.4}{2004/08/24}{Added optional check}
+% \oarg{prefix}\marg{family}\\
+% Macro to define a key in a family. Notice the use of the |KV| prefix
+% as default prefix. This is done to allow setting both \pf{keyval} and
+% \pf{xkeyval} keys with a single command. This top level command first
+% checks for an optional \meta{prefix} and the mandatory \meta{family}.
+% \begin{macrocode}
+\def\define@key{\XKV@testoptb\XKV@define@key}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@define@key}
+% \marg{key}\\
+% Check for an optional default value. If none present, define the
+% key macro, else continue to eat the default value.
+% \begin{macrocode}
+\def\XKV@define@key#1{%
+ \@ifnextchar[{\XKV@d@fine@k@y{#1}}{%
+ \expandafter\def\csname\XKV@header#1\endcsname####1%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@fine@key}
+% \marg{key}\oarg{default}\\
+% Defines the key macro and the default value macro.
+% \begin{macrocode}
+\def\XKV@d@fine@k@y#1[#2]{%
+ \XKV@define@default{#1}{#2}%
+ \expandafter\def\csname\XKV@header#1\endcsname##1%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\define@cmdkey}
+% \oarg{prefix}\marg{family}\oarg{mp}\marg{key}\\
+% Define a command key.
+% Test for optional \meta{prefix}, mandatory \meta{family}, optional
+% \meta{mp} `macro prefix' and mandatory \meta{key} name.
+% \begin{macrocode}
+\def\define@cmdkey{\XKV@testoptd\XKV@define@cmdkey{cmd}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@define@cmdkey}
+% \marg{mp}\marg{key}\oarg{default}\marg{function}\\
+% \changes{v2.5c}{2005/07/10}{Avoid initializing control sequence as \cs{relax}}
+% Define the default value macro and the key macro. The key macro first
+% defines the control sequence formed by the \meta{mp} and \meta{key}
+% to expand to the user input and then executes the \meta{function}.
+% \begin{macrocode}
+\def\XKV@define@cmdkey#1#2[#3]#4{%
+ \ifXKV@st\XKV@define@default{#2}{#3}\fi
+ \def\XKV@tempa{\expandafter\def\csname\XKV@header#2\endcsname####1}%
+ \begingroup\expandafter\endgroup\expandafter\XKV@tempa\expandafter
+ {\expandafter\def\csname#1#2\endcsname{##1}#4}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\define@cmdkeys}
+% \oarg{prefix}\marg{family}\oarg{mp}\marg{keys}\\
+% Define multiple command keys.
+% \begin{macrocode}
+\def\define@cmdkeys{\XKV@testoptd\XKV@define@cmdkeys{cmd}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@define@cmdkeys}
+% \marg{mp}\marg{keys}\oarg{default}\\
+% Loop over \meta{keys} and define a command key for every entry.
+% \begin{macrocode}
+\def\XKV@define@cmdkeys#1#2[#3]{%
+ \XKV@sp@deflist\XKV@tempa{#2}%
+ \XKV@for@o\XKV@tempa\XKV@tempa{%
+ \edef\XKV@tempa{\noexpand\XKV@define@cmdkey{#1}{\XKV@tempa}}%
+ \XKV@tempa[#3]{}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\define@choicekey}
+% |*+|\oarg{prefix}\marg{family}\\
+% Choice keys. First check optional star, plus and prefix and store the
+% family.
+% \begin{macrocode}
+\def\define@choicekey{\XKV@testopta{\XKV@testoptb\XKV@define@choicekey}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@define@choicekey}
+% \marg{key}\\
+% Check for optional storage bins for the input and the number of
+% the input in the list of allowed inputs.
+% \begin{macrocode}
+\def\XKV@define@choicekey#1{\@testopt{\XKV@d@fine@choicekey{#1}}{}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@fine@choicekey}
+% \marg{key}\oarg{bin}\marg{allowed}\\
+% Store the storage bin and the list of allowed inputs for later use.
+% After that, check for an optional default value.
+% \begin{macrocode}
+\def\XKV@d@fine@choicekey#1[#2]#3{%
+ \toks@{#2}%
+ \XKV@sp@deflist\XKV@tempa{#3}\XKV@toks\expandafter{\XKV@tempa}%
+ \@ifnextchar[{\XKV@d@fine@ch@icekey{#1}}{\XKV@d@fine@ch@ic@key{#1}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@fine@ch@icekey}
+% \marg{key}\oarg{default}\\
+% Define the default value macro if a default value was specified.
+% \begin{macrocode}
+\def\XKV@d@fine@ch@icekey#1[#2]{%
+ \XKV@define@default{#1}{#2}%
+ \XKV@d@fine@ch@ic@key{#1}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@fine@ch@ic@key}
+% \marg{key}\\
+% Eat correct number of arguments.
+% \begin{macrocode}
+\def\XKV@d@fine@ch@ic@key#1{%
+ \ifXKV@pl\XKV@afterelsefi
+ \expandafter\XKV@d@f@ne@ch@ic@k@y
+ \else\XKV@afterfi
+ \expandafter\XKV@d@f@ne@ch@ic@key
+ \fi
+ \csname\XKV@header#1\endcsname
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@f@ne@ch@ic@key}
+% \meta{key macro}\marg{function}\\
+% Eat one argument and pass it on to the macro that will define the key macro.
+% \begin{macrocode}
+\def\XKV@d@f@ne@ch@ic@key#1#2{\XKV@d@f@n@@ch@ic@k@y#1{{#2}}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@f@ne@ch@ic@k@y}
+% \meta{key macro}\marg{function1}\marg{function2}\\
+% Eat two arguments and pass these on to the macro that will define the key macro.
+% \meta{fucntion1} will be executed on correct input, \meta{function2}
+% on incorrect input.
+% \begin{macrocode}
+\def\XKV@d@f@ne@ch@ic@k@y#1#2#3{\XKV@d@f@n@@ch@ic@k@y#1{{#2}{#3}}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@f@n@@ch@ic@k@y}
+% \meta{key macro}\marg{function}\\
+% Create the key macros. |\XKV@checkchoice| will be used to check the choice
+% and execute one of its mandatory arguments.
+% \begin{macrocode}
+\def\XKV@d@f@n@@ch@ic@k@y#1#2{%
+ \edef#1##1{%
+ \ifXKV@st\noexpand\XKV@sttrue\else\noexpand\XKV@stfalse\fi
+ \ifXKV@pl\noexpand\XKV@pltrue\else\noexpand\XKV@plfalse\fi
+ \noexpand\XKV@checkchoice[\the\toks@]{##1}{\the\XKV@toks}%
+ }%
+ \def\XKV@tempa{\def#1####1}%
+ \expandafter\XKV@tempa\expandafter{#1{##1}#2}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\define@boolkey}
+% |+|\oarg{prefix}\marg{family}\oarg{mp}\marg{key}\\
+% Define a boolean key. This macro checks for an optional |+|, an
+% optional \meta{prefix}, the mandatory \meta{family}, an optional
+% \meta{mp} (`macro prefix') and the mandatory \meta{key} name.
+% \begin{macrocode}
+\def\define@boolkey{\XKV@t@stopta{\XKV@testoptd\XKV@define@boolkey{}}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@define@boolkey}
+% \marg{mp}\marg{key}\oarg{default}\\
+% Decide to eat 1 or 2 mandatory arguments for the key macro. Further,
+% construct the control sequence for the key macro and the one for the
+% if.
+% \begin{macrocode}
+\def\XKV@define@boolkey#1#2[#3]{%
+ \ifXKV@pl\XKV@afterelsefi
+ \expandafter\XKV@d@f@ne@boolkey
+ \else\XKV@afterfi
+ \expandafter\XKV@d@fine@boolkey
+ \fi
+ \csname\XKV@header#2\endcsname{#2}{#1#2}{#3}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@fine@boolkey}
+% \changes{v2.5 }{2005/05/07}{Removed \cs{relax}}
+% \meta{key macro}\marg{key}\marg{if name}\marg{default}\marg{function}\\
+% Eat one mandatory key function and pass it. Insert `setting the if'.
+% \begin{macrocode}
+\def\XKV@d@fine@boolkey#1#2#3#4#5{%
+ \XKV@d@f@ne@b@olkey#1{#2}{#3}{#4}%
+ {{\csname#3\XKV@resa\endcsname#5}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@f@ne@boolkey}
+% \changes{v2.5 }{2005/05/07}{Removed \cs{relax}}
+% \meta{key macro}\marg{key}\marg{if name}\marg{default}\marg{func1}\marg{func2}\\
+% Eat two mandatory key functions and pass them. Insert `setting the if'.
+% \begin{macrocode}
+\def\XKV@d@f@ne@boolkey#1#2#3#4#5#6{%
+ \XKV@d@f@ne@b@olkey#1{#2}{#3}{#4}%
+ {{\csname#3\XKV@resa\endcsname#5}{#6}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@f@ne@b@olkey}
+% \meta{key macro}\marg{key}\marg{if name}\marg{default}\marg{function}\\
+% Create the if, the default value macro (if a default value was present)
+% and the key macro. We use |\XKV@checkchoice| internally to check the
+% input and |\XKV@resa| to store the user input and pass it to setting
+% the conditional.
+% \begin{macrocode}
+\def\XKV@d@f@ne@b@olkey#1#2#3#4#5{%
+ \expandafter\newif\csname if#3\endcsname
+ \ifXKV@st\XKV@define@default{#2}{#4}\fi
+ \ifXKV@pl
+ \def#1##1{\XKV@pltrue\XKV@sttrue
+ \XKV@checkchoice[\XKV@resa]{##1}{true,false}#5%
+ }%
+ \else
+ \def#1##1{\XKV@plfalse\XKV@sttrue
+ \XKV@checkchoice[\XKV@resa]{##1}{true,false}#5%
+ }%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\define@boolkeys}
+% \oarg{prefix}\marg{family}\oarg{mp}\marg{keys}\\
+% Define multiple boolean keys without user specified key function.
+% The key will, of course, still set the if with user input.
+% \begin{macrocode}
+\def\define@boolkeys{\XKV@plfalse\XKV@testoptd\XKV@define@boolkeys{}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@define@boolkeys}
+% \marg{mp}\marg{keys}\oarg{default}\\
+% Loop over the list of \meta{keys} and create a boolean key for
+% every entry.
+% \begin{macrocode}
+\def\XKV@define@boolkeys#1#2[#3]{%
+ \XKV@sp@deflist\XKV@tempa{#2}%
+ \XKV@for@o\XKV@tempa\XKV@tempa{%
+ \expandafter\XKV@d@fine@boolkeys\expandafter{\XKV@tempa}{#1}{#3}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@fine@boolkeys}
+% \marg{key}\marg{mp}\marg{default}\\
+% Use |\XKV@d@f@ne@b@olkey| internally to define the if, the default
+% value macro (if present) and the key macro.
+% \begin{macrocode}
+\def\XKV@d@fine@boolkeys#1#2#3{%
+ \expandafter\XKV@d@f@ne@b@olkey\csname\XKV@header#1\endcsname
+ {#1}{#2#1}{#3}{{\csname#2#1\XKV@resa\endcsname}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@cc}
+% This macro is used inside key macros to perform input checks. This
+% is the user interface to |\XKV@checkchoice| and we only use the
+% latter internally to avoid slow parsings of optional |*| and |+|.
+% \begin{macrocode}
+\def\XKV@cc{\XKV@testopta{\@testopt\XKV@checkchoice{}}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@checkchoice}
+% \oarg{bin}\marg{input}\marg{allowed}\\
+% Checks whether \meta{bin} contains at least one control sequence and
+% converts \meta{input} and \meta{allowed} to lowercase if requested.
+% If \meta{bin} is empty, perform the fast |\in@| check immediately.
+% Else, determine whether the bin contains one or two tokens. For the
+% first alternative, we can still use the fast |\in@| check. Notice
+% that this macro uses settings for |\ifXKV@st| and |\ifXKV@pl|.
+% \begin{macrocode}
+\def\XKV@checkchoice[#1]#2#3{%
+ \def\XKV@tempa{#1}%
+ \ifXKV@st\lowercase{\fi
+ \ifx\XKV@tempa\@empty
+ \def\XKV@tempa{\XKV@ch@ckch@ice\@nil{#2}{#3}}%
+ \else
+ \def\XKV@tempa{\XKV@ch@ckchoice#1\@nil{#2}{#3}}%
+ \fi
+ \ifXKV@st}\fi\XKV@tempa
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@ch@ckchoice}
+% \meta{bin1}\meta{bin2}|\@nil|\marg{input}\marg{allowed}\\
+% Check whether \meta{bin2} is empty. In that case, only the \meta{input} should
+% be saved and we can continue with the fast |\in@| check. If not, also
+% the number of the input in the \meta{allowed} list should be saved
+% and we need to do a slower while type of loop.
+% \begin{macrocode}
+\def\XKV@ch@ckchoice#1#2\@nil#3#4{%
+ \def\XKV@tempa{#2}%
+ \ifx\XKV@tempa\@empty\XKV@afterelsefi
+ \XKV@ch@ckch@ice#1{#3}{#4}%
+ \else\XKV@afterfi
+ \XKV@@ch@ckchoice#1#2{#3}{#4}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@ch@ckch@ice}
+% \meta{bin}\marg{input}\marg{allowed}\\
+% Checks whether \meta{input} is in the list \meta{allowed} and perform
+% actions accordingly.
+% \begin{macrocode}
+\def\XKV@ch@ckch@ice#1#2#3{%
+ \def\XKV@tempa{#1}%
+% \end{macrocode}
+% If we have a \meta{bin}, store the input there.
+% \begin{macrocode}
+ \ifx\XKV@tempa\@nnil\let\XKV@tempa\@empty\else
+ \def\XKV@tempa{\def#1{#2}}%
+ \fi
+ \in@{,#2,}{,#3,}%
+ \ifin@
+% \end{macrocode}
+% The \meta{input} is allowed.
+% \begin{macrocode}
+ \ifXKV@pl
+% \end{macrocode}
+% If we have a |+|, there are two functions. Execute the first.
+% \begin{macrocode}
+ \XKV@addtomacro@n\XKV@tempa\@firstoftwo
+ \else
+% \end{macrocode}
+% Else, we have one function; execute it.
+% \begin{macrocode}
+ \XKV@addtomacro@n\XKV@tempa\@firstofone
+ \fi
+ \else
+% \end{macrocode}
+% If we have a |+|, there are two functions. Execute the second.
+% \begin{macrocode}
+ \ifXKV@pl
+ \XKV@addtomacro@n\XKV@tempa\@secondoftwo
+ \else
+% \end{macrocode}
+% Else, raise an error and gobble the one function.
+% \begin{macrocode}
+ \XKV@toks{#2}%
+ \XKV@err{value `\the\XKV@toks' is not allowed}%
+ \XKV@addtomacro@n\XKV@tempa\@gobble
+ \fi
+ \fi
+ \XKV@tempa
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@@ch@ckchoice}
+% \meta{bin1}\meta{bin2}\marg{input}\marg{allowed}\\
+% Walk over the \meta{allowed} list and compare each entry with the
+% \meta{input}. The input is saved in \meta{bin1}, the number of the
+% \meta{input} in the \meta{allowed} list (starting at zero) is saved
+% in \meta{bin2}. If the \meta{input} is not allowed, \meta{bin2} will
+% be defined to contain |-1|.
+% \begin{macrocode}
+\def\XKV@@ch@ckchoice#1#2#3#4{%
+% \end{macrocode}
+% Save the current value of the counter as to avoid disturbing it.
+% We don't use a group as that takes a lot of memory and requires some
+% more tokens (for global definitions).
+% \begin{macrocode}
+ \edef\XKV@tempa{\the\count@}\count@\z@
+% \end{macrocode}
+% The input.
+% \begin{macrocode}
+ \def\XKV@tempb{#3}%
+% \end{macrocode}
+% Define the while loop.
+% \begin{macrocode}
+ \def\XKV@tempc##1,{%
+ \def#1{##1}%
+ \ifx#1\@nnil
+% \end{macrocode}
+% The \meta{input} was not in \meta{allowed}. Set the number to |-1|.
+% \begin{macrocode}
+ \def#1{#3}\def#2{-1}\count@\XKV@tempa
+ \ifXKV@pl
+% \end{macrocode}
+% Execute the macro for the case that input was not allowed.
+% \begin{macrocode}
+ \let\XKV@tempd\@secondoftwo
+ \else
+% \end{macrocode}
+% If that function does not exist, raise a generic error and gobble
+% the function to be executed on good input.
+% \begin{macrocode}
+ \XKV@toks{#3}%
+ \XKV@err{value `\the\XKV@toks' is not allowed}%
+ \let\XKV@tempd\@gobble
+ \fi
+ \else
+ \ifx#1\XKV@tempb
+% \end{macrocode}
+% We found \meta{input} in \meta{allowed}.
+% Save the number of the \meta{input} in the list \meta{allowed}.
+% \begin{macrocode}
+ \edef#2{\the\count@}\count@\XKV@tempa
+ \ifXKV@pl
+ \let\XKV@tempd\XKV@@ch@ckch@ice
+ \else
+ \let\XKV@tempd\XKV@@ch@ckch@ic@
+ \fi
+ \else
+% \end{macrocode}
+% Increase counter and check next item in the list \meta{allowed}.
+% \begin{macrocode}
+ \advance\count@\@ne
+ \let\XKV@tempd\XKV@tempc
+ \fi
+ \fi
+ \XKV@tempd
+ }%
+% \end{macrocode}
+% Start the while loop.
+% \begin{macrocode}
+ \XKV@tempc#4,\@nil,%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@@ch@ckch@ice}
+% \begin{macro}{\XKV@@ch@ckch@ic@}
+% \meta{text}|\@nil,|\\
+% Gobble remaining \meta{text} and execute the proper key function.
+% \begin{macrocode}
+\def\XKV@@ch@ckch@ice#1\@nil,{\@firstoftwo}
+\def\XKV@@ch@ckch@ic@#1\@nil,{\@firstofone}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\key@ifundefined}
+% This macro allows checking if a key is defined in a family from
+% a list of families. Check for an optional prefix.
+% \begin{macrocode}
+\def\key@ifundefined{\@testopt\XKV@key@ifundefined{KV}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@key@ifundefined}
+% \oarg{prefix}\marg{fams}\\
+% This macro is split in two parts so that |\XKV@p@x| can use only
+% the main part of the macro. First we save the prefix and the list
+% of families.
+% \begin{macrocode}
+\def\XKV@key@ifundefined[#1]#2{%
+ \XKV@makepf{#1}%
+ \XKV@checksanitizeb{#2}\XKV@fams
+ \expandafter\XKV@sp@deflist\expandafter
+ \XKV@fams\expandafter{\XKV@fams}%
+ \XKV@key@if@ndefined
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@key@if@ndefined}
+% \marg{key}\\
+% Loop over the list of families until we find the key in a family.
+% \begin{macrocode}
+\def\XKV@key@if@ndefined#1{%
+ \XKV@knftrue
+ \KV@@sp@def\XKV@tkey{#1}%
+% \end{macrocode}
+% Loop over possible families.
+% \begin{macrocode}
+ \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{%
+% \end{macrocode}
+% Set the header.
+% \begin{macrocode}
+ \XKV@makehd\XKV@tfam
+% \end{macrocode}
+% Check whether the macro for the key is defined.
+% \begin{macrocode}
+ \XKV@ifundefined{\XKV@header\XKV@tkey}{}{\XKV@knffalse}%
+ }%
+% \end{macrocode}
+% Execute one of the final two arguments depending on state of |\XKV@knf|.
+% \begin{macrocode}
+ \ifXKV@knf
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\disable@keys}
+% \oarg{prefix}\marg{family}\\
+% Macro that make a key produce a warning on use.
+% \begin{macrocode}
+\def\disable@keys{\XKV@testoptb\XKV@disable@keys}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@disable@keys}
+% \marg{keys}\\
+% Workhorse for |\disable@keys| which redefines a list of key macro
+% to produce a warning.
+% \begin{macrocode}
+\def\XKV@disable@keys#1{%
+ \XKV@checksanitizeb{#1}\XKV@tempa
+ \XKV@for@o\XKV@tempa\XKV@tempa{%
+ \XKV@ifundefined{\XKV@header\XKV@tempa}{%
+ \XKV@err{key `\XKV@tempa' undefined}%
+ }{%
+ \edef\XKV@tempb{%
+ \noexpand\XKV@warn{key `\XKV@tempa' has been disabled}%
+ }%
+ \XKV@ifundefined{\XKV@header\XKV@tempa @default}{%
+ \edef\XKV@tempc{\noexpand\XKV@define@key{\XKV@tempa}}%
+ }{%
+ \edef\XKV@tempc{\noexpand\XKV@define@key{\XKV@tempa}[]}%
+ }%
+ \expandafter\XKV@tempc\expandafter{\XKV@tempb}%
+ }%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\presetkeys}
+% \begin{macro}{\gpresetkeys}
+% \changes{v1.7}{2004/11/25}{Made incremental}
+% \oarg{prefix}\marg{family}\\
+% This provides the presetting system. The macro works incrementally:
+% keys that have been preset before will overwrite the old preset
+% values, new ones will be added to the end of the preset list.
+% \begin{macrocode}
+\def\presetkeys{\XKV@stfalse\XKV@testoptb\XKV@presetkeys}
+\def\gpresetkeys{\XKV@sttrue\XKV@testoptb\XKV@presetkeys}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@presetkeys}
+% \marg{head presets}\marg{tail presets}\\
+% Execute the merging macro |\XKV@pr@setkeys| for both head and tail
+% presets.
+% \begin{macrocode}
+\def\XKV@presetkeys#1#2{%
+ \XKV@pr@setkeys{#1}{preseth}%
+ \XKV@pr@setkeys{#2}{presett}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@pr@setkeys}
+% \marg{presets}\marg{postfix}\\
+% Check whether presets have already been defined. If not, define them
+% and do not start the merging macro. Otherwise, create the control
+% sequence that stores these presets and start merging.
+% \begin{macrocode}
+\def\XKV@pr@setkeys#1#2{%
+ \XKV@ifundefined{XKV@\XKV@header#2}{%
+ \XKV@checksanitizea{#1}\XKV@tempa
+ \ifXKV@st\expandafter\global\fi\expandafter\def\csname
+ XKV@\XKV@header#2\expandafter\endcsname\expandafter{\XKV@tempa}%
+ }{%
+ \expandafter\XKV@merge\csname XKV@\XKV@header
+ #2\endcsname{#1}\XKV@getkeyname
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\delpresetkeys}
+% \begin{macro}{\gdelpresetkeys}
+% \oarg{prefix}\marg{family}\\
+% Macros to remove entries from presets.
+% \begin{macrocode}
+\def\delpresetkeys{\XKV@stfalse\XKV@testoptb\XKV@delpresetkeys}
+\def\gdelpresetkeys{\XKV@sttrue\XKV@testoptb\XKV@delpresetkeys}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@delpresetkeys}
+% \marg{head key list}\marg{tail key list}\\
+% Run the main macro for both head and tail presets.
+% \begin{macrocode}
+\def\XKV@delpresetkeys#1#2{%
+ \XKV@d@lpresetkeys{#1}{preseth}%
+ \XKV@d@lpresetkeys{#2}{presett}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@lpresetkeys}
+% \marg{key list}\marg{postfix}\\
+% Check whether presets have been saved and if so, start deletion
+% algorithm. Supply the macro |\XKV@getkeyname| to retrieve key names
+% from entries.
+% \begin{macrocode}
+\def\XKV@d@lpresetkeys#1#2{%
+ \XKV@ifundefined{XKV@\XKV@header#2}{%
+ \XKV@err{no presets defined for `\XKV@header'}%
+ }{%
+ \expandafter\XKV@delete\csname XKV@\XKV@header
+ #2\endcsname{#1}\XKV@getkeyname
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\unpresetkeys}
+% \begin{macro}{\gunpresetkeys}
+% \oarg{prefix}\marg{family}\\
+% Removes presets for a particular family.
+% \begin{macrocode}
+\def\unpresetkeys{\XKV@stfalse\XKV@testoptb\XKV@unpresetkeys}
+\def\gunpresetkeys{\XKV@sttrue\XKV@testoptb\XKV@unpresetkeys}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@unpresetkeys}
+% Undefine the preset macros. We make them undefined since this will
+% make them appear undefined to both versions of the macro |\XKV@ifundefined|.
+% Making the macros |\relax| would work in the case that no \eTeX\ is
+% available (hence using |\ifx\csname|), but doesn't work when \eTeX\
+% is used (and using |\ifcsname|).
+% \begin{macrocode}
+\def\XKV@unpresetkeys{%
+ \XKV@ifundefined{XKV@\XKV@header preseth}{%
+ \XKV@err{no presets defined for `\XKV@header'}%
+ }{%
+ \ifXKV@st\expandafter\global\fi\expandafter\let
+ \csname XKV@\XKV@header preseth\endcsname\@undefined
+ \ifXKV@st\expandafter\global\fi\expandafter\let
+ \csname XKV@\XKV@header presett\endcsname\@undefined
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\savekeys}
+% \begin{macro}{\gsavekeys}
+% \oarg{prefix}\marg{family}\\
+% Store a list of keys of a family that should always be saved. The
+% macro works incrementally and avoids duplicate entries in the list.
+% \begin{macrocode}
+\def\savekeys{\XKV@stfalse\XKV@testoptb\XKV@savekeys}
+\def\gsavekeys{\XKV@sttrue\XKV@testoptb\XKV@savekeys}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@savekeys}
+% \marg{key list}\\
+% Check whether something has been saved before. If not, start merging.
+% \begin{macrocode}
+\def\XKV@savekeys#1{%
+ \XKV@ifundefined{XKV@\XKV@header save}{%
+ \XKV@checksanitizeb{#1}\XKV@tempa
+ \ifXKV@st\expandafter\global\fi\expandafter\def\csname XKV@%
+ \XKV@header save\expandafter\endcsname\expandafter{\XKV@tempa}%
+ }{%
+ \expandafter\XKV@merge\csname XKV@\XKV@header
+ save\endcsname{#1}\XKV@getsg
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\delsavekeys}
+% \begin{macro}{\gdelsavekeys}
+% \oarg{prefix}\marg{family}\\
+% Remove entries from the list of save keys.
+% \begin{macrocode}
+\def\delsavekeys{\XKV@stfalse\XKV@testoptb\XKV@delsavekeys}
+\def\gdelsavekeys{\XKV@sttrue\XKV@testoptb\XKV@delsavekeys}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@delsavekeys}
+% \marg{key list}\\
+% Check whether save keys are defined and if yes, start deletion
+% algorithm. Use the macro |\XKV@getsg| to retrieve key names from
+% entries.
+% \begin{macrocode}
+\def\XKV@delsavekeys#1{%
+ \XKV@ifundefined{XKV@\XKV@header save}{%
+ \XKV@err{no save keys defined for `\XKV@header'}%
+ }{%
+ \expandafter\XKV@delete\csname XKV@\XKV@header
+ save\endcsname{#1}\XKV@getsg
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\unsavekeys}
+% \begin{macro}{\gunsavekeys}
+% \oarg{prefix}\marg{family}\\
+% Similar to |\unpresetkeys|, but removes the `save keys list' for a
+% particular family.
+% \begin{macrocode}
+\def\unsavekeys{\XKV@stfalse\XKV@testoptb\XKV@unsavekeys}
+\def\gunsavekeys{\XKV@sttrue\XKV@testoptb\XKV@unsavekeys}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@unsavekeys}
+% Workhorse for |\unsavekeys|.
+% \begin{macrocode}
+\def\XKV@unsavekeys{%
+ \XKV@ifundefined{XKV@\XKV@header save}{%
+ \XKV@err{no save keys defined for `\XKV@header'}%
+ }{%
+ \ifXKV@st\expandafter\global\fi\expandafter\let
+ \csname XKV@\XKV@header save\endcsname\@undefined
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\setkeys}
+% |*+|\oarg{prefix}\marg{families}\\
+% Set keys. The starred version does not produce errors, but appends
+% keys that cannot be located to the list in |\XKV@rm|. The plus
+% version sets keys in all families that are supplied.
+% \begin{macrocode}
+\def\setkeys{\XKV@testopta{\XKV@testoptc\XKV@setkeys}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@setkeys}
+% \oarg{na}\marg{key=value list}\\
+% \changes{v1.8a}{2004/12/20}{Solved small bug}
+% Workhorse for |\setkeys|.
+% \begin{macrocode}
+\def\XKV@setkeys[#1]#2{%
+ \XKV@checksanitizea{#2}\XKV@resb
+ \let\XKV@naa\@empty
+% \end{macrocode}
+% Retrieve a list of key names from the user input.
+% \begin{macrocode}
+ \XKV@for@o\XKV@resb\XKV@tempa{%
+ \expandafter\XKV@g@tkeyname\XKV@tempa=\@nil\XKV@tempa
+ \XKV@addtolist@x\XKV@naa\XKV@tempa
+ }%
+% \end{macrocode}
+% Initialize the remaining keys.
+% \begin{macrocode}
+ \let\XKV@rm\@empty
+% \end{macrocode}
+% Now scan the list of families for preset keys and set user input keys.
+% \begin{macrocode}
+ \XKV@usepresetkeys{#1}{preseth}%
+ \expandafter\XKV@s@tkeys\expandafter{\XKV@resb}{#1}%
+ \XKV@usepresetkeys{#1}{presett}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@usepresetkeys}
+% \marg{na}\marg{postfix}\\
+% Loop over the list of families and check them for preset keys. If
+% present, set them right away, taking into account the keys which
+% are set by the user, available in the |\XKV@naa| list.
+% \begin{macrocode}
+\def\XKV@usepresetkeys#1#2{%
+ \XKV@presettrue
+ \XKV@for@eo\XKV@fams\XKV@tfam{%
+ \XKV@makehd\XKV@tfam
+ \XKV@ifundefined{XKV@\XKV@header#2}{}{%
+ \XKV@toks\expandafter\expandafter\expandafter
+ {\csname XKV@\XKV@header#2\endcsname}%
+ \@expandtwoargs\XKV@s@tkeys{\the\XKV@toks}%
+ {\XKV@naa\ifx\XKV@naa\@empty\else,\fi#1}%
+ }%
+ }%
+ \XKV@presetfalse
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@s@tkeys}
+% \marg{key=value list}\marg{na}\\
+% This macro starts the loop over the |key=value| list. Do not set
+% keys in the list \meta{na}.
+% \begin{macrocode}
+\def\XKV@s@tkeys#1#2{%
+% \end{macrocode}
+% Define the list of key names which should be ignored.
+% \begin{macrocode}
+ \XKV@sp@deflist\XKV@na{#2}%
+% \end{macrocode}
+% Loop over the key=value list.
+% \begin{macrocode}
+ \XKV@for@n{#1}\CurrentOption{%
+% \end{macrocode}
+% Split key and value.
+% \begin{macrocode}
+ \expandafter\XKV@s@tk@ys\CurrentOption==\@nil
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@s@tk@ys}
+% \changes{v1.4}{2004/08/24}{Made macro more efficient}
+% \changes{v2.4}{2005/03/31}{Added \cs{global} to make \cs{XKV@rm}
+% survive when \cs{setkeys} executed in a group.}
+% \meta{key}|=|\meta{value}|=#3\@nil|\\
+% Split key name and value (if present). If |#3| non-empty, there was
+% no |=|\meta{value}.
+% \begin{macrocode}
+\def\XKV@s@tk@ys#1=#2=#3\@nil{%
+% \end{macrocode}
+% Check for |\savevalue| and |\gsavevalue| and remove spaces from around the key name.
+% \begin{macrocode}
+ \XKV@g@tkeyname#1=\@nil\XKV@tkey
+ \expandafter\KV@@sp@def\expandafter\XKV@tkey\expandafter{\XKV@tkey}%
+% \end{macrocode}
+% If the key is empty and a value has been specified, generate an error.
+% \begin{macrocode}
+ \ifx\XKV@tkey\@empty
+ \XKV@toks{#2}%
+ \ifcat$\the\XKV@toks$\else
+ \XKV@err{no key specified for value `\the\XKV@toks'}%
+ \fi
+ \else
+% \end{macrocode}
+% If in the |\XKV@na| list, ignore the key.
+% \begin{macrocode}
+ \@expandtwoargs\in@{,\XKV@tkey,}{,\XKV@na,}%
+ \ifin@\else
+ \XKV@knftrue
+ \KV@@sp@def\XKV@tempa{#2}%
+ \ifXKV@preset\XKV@s@tk@ys@{#3}\else
+ \ifXKV@pl
+% \end{macrocode}
+% If a command with a |+| is used, set keys in all families on the
+% list.
+% \begin{macrocode}
+ \XKV@for@eo\XKV@fams\XKV@tfam{%
+ \XKV@makehd\XKV@tfam
+ \XKV@s@tk@ys@{#3}%
+ }%
+ \else
+% \end{macrocode}
+% Else, scan the families on the list but stop when the key is found
+% or when the list has run out.
+% \begin{macrocode}
+ \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{%
+ \XKV@makehd\XKV@tfam
+ \XKV@s@tk@ys@{#3}%
+ }%
+ \fi
+ \fi
+ \ifXKV@knf
+ \ifXKV@inpox
+% \end{macrocode}
+% We are in the options section. Try to use the macro defined by
+% |\DeclareOptionX*|.
+% \begin{macrocode}
+ \ifx\XKV@doxs\relax
+% \end{macrocode}
+% For classes, ignore unknown (possibly global) options. For packages,
+% raise the standard \LaTeX\ error.
+% \begin{macrocode}
+ \ifx\@currext\@clsextension\else
+ \let\CurrentOption\XKV@tkey\@unknownoptionerror
+ \fi
+% \end{macrocode}
+% Pass the option through |\DeclareOptionX*|.
+% \begin{macrocode}
+ \else\XKV@doxs\fi
+ \else
+% \end{macrocode}
+% If not in the options section, raise an error or add the key to the
+% list in |\XKV@rm| when |\setkeys*| has been used.
+% \begin{macrocode}
+ \ifXKV@st
+ \global\XKV@addtolist@o\XKV@rm\CurrentOption
+ \else
+ \XKV@err{`\XKV@tkey' undefined in families `\XKV@fams'}%
+ \fi
+ \fi
+ \else
+% \end{macrocode}
+% Remove global options set by the document class from |\@unusedoptionlist|.
+% Global options set by other packages or classes will be removed by
+% |\ProcessOptionsX*|.
+% \begin{macrocode}
+ \ifXKV@inpox\ifx\XKV@testclass\XKV@documentclass
+ \expandafter\XKV@useoption\expandafter{\CurrentOption}%
+ \fi\fi
+ \fi
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@s@tk@ys@}
+% \marg{ind}\\
+% This macro coordinates the work of setting a key. \meta{ind} is an
+% indicator for the presence of a user submitted value for the key. If
+% empty, no value was present.
+% \begin{macrocode}
+\def\XKV@s@tk@ys@#1{%
+% \end{macrocode}
+% Check whether the key macro exists.
+% \begin{macrocode}
+ \XKV@ifundefined{\XKV@header\XKV@tkey}{}{%
+ \XKV@knffalse
+% \end{macrocode}
+% Check global setting by |\savekeys| to know whether or not to save
+% the value of the key at hand.
+% \begin{macrocode}
+ \XKV@ifundefined{XKV@\XKV@header save}{}{%
+ \expandafter\XKV@testsavekey\csname XKV@\XKV@header
+ save\endcsname\XKV@tkey
+ }%
+% \end{macrocode}
+% Save the value of a key.
+% \begin{macrocode}
+ \ifXKV@rkv
+ \ifXKV@sg\expandafter\global\fi\expandafter\let
+ \csname XKV@\XKV@header\XKV@tkey @value\endcsname\XKV@tempa
+ \fi
+% \end{macrocode}
+% Replace pointers by saved values.
+% \begin{macrocode}
+ \expandafter\XKV@replacepointers\expandafter{\XKV@tempa}%
+% \end{macrocode}
+% If no value was present, use the default value macro, if one exists.
+% Otherwise, issue an error.
+% \begin{macrocode}
+ \ifx\@empty#1\@empty\XKV@afterelsefi
+ \XKV@ifundefined{\XKV@header\XKV@tkey @default}{%
+ \XKV@err{no value specified for key `\XKV@tkey'}%
+ }{%
+ \expandafter\expandafter\expandafter\XKV@default
+ \csname\XKV@header\XKV@tkey @default\endcsname\@nil
+ }%
+ \else\XKV@afterfi
+% \end{macrocode}
+% Save state in case the key executes |\setkeys| or |\XKV@cc|.
+% \begin{macrocode}
+ \XKV@srstate{@\romannumeral\XKV@depth}{}%
+% \end{macrocode}
+% Execute the key.
+% \begin{macrocode}
+ \csname\XKV@header\XKV@tkey\expandafter
+ \endcsname\expandafter{\XKV@tempa}\relax
+% \end{macrocode}
+% Restore the current state.
+% \begin{macrocode}
+ \XKV@srstate{}{@\romannumeral\XKV@depth}%
+ \fi
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@testsavekey}
+% \meta{save key list}\meta{key name}\\
+% This macro checks whether the key in macro \meta{key name} appears in the
+% save list in macro \meta{save key list}. Furthermore, it checks whether or not to
+% save the key globally. In other words, that |\global{key}| is in
+% the list.
+% \begin{macrocode}
+\def\XKV@testsavekey#1#2{%
+ \ifXKV@rkv\else
+ \XKV@for@o#1\XKV@resa{%
+ \expandafter\XKV@ifcmd\expandafter{\XKV@resa}\global\XKV@resa{%
+ \ifx#2\XKV@resa
+ \XKV@rkvtrue\XKV@sgtrue
+ \fi
+ }{%
+ \ifx#2\XKV@resa
+ \XKV@rkvtrue\XKV@sgfalse
+ \fi
+ }%
+ }%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@replacepointers}
+% \begin{macro}{\XKV@r@placepointers}
+% \changes{v1.8d}{2005/01/02}{Added \cs{XKV@afterfi} to avoid capacity
+% problems when too many pointers present}
+% \changes{v1.9}{2005/01/16}{Added back linking test}
+% \changes{v2.0}{2005/01/30}{Simplified}
+% \marg{key=value list}\\
+% Replaces all pointers by their saved values. The result is stored in
+% |\XKV@tempa|. We feed the replacement and the following tokens again to the
+% macro to replace nested pointers. It stops when no pointers are
+% found anymore. We keep a list of pointers replaced already for this
+% key in |\XKV@resa| so we can check whether we are running in circles.
+% \begin{macrocode}
+\def\XKV@replacepointers#1{%
+ \let\XKV@tempa\@empty
+ \let\XKV@resa\@empty
+ \XKV@r@placepointers#1\usevalue\@nil
+}
+\def\XKV@r@placepointers#1\usevalue#2{%
+ \XKV@addtomacro@n\XKV@tempa{#1}%
+ \def\XKV@tempb{#2}%
+ \ifx\XKV@tempb\@nnil\else\XKV@afterfi
+ \XKV@ifundefined{XKV@\XKV@header#2@value}{%
+ \XKV@err{no value recorded for key `#2'; ignored}%
+ \XKV@r@placepointers
+ }{%
+ \@expandtwoargs\in@{,#2,}{,\XKV@resa,}%
+ \ifin@\XKV@afterelsefi
+ \XKV@err{back linking pointers; pointer replacement canceled}%
+ \else\XKV@afterfi
+ \XKV@addtolist@x\XKV@resa{#2}%
+ \expandafter\expandafter\expandafter\XKV@r@placepointers
+ \csname XKV@\XKV@header#2@value\endcsname
+ \fi
+ }%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@default}
+% \changes{v2.0}{2005/01/30}{Repaired adding extra braces when executing default value}
+% \meta{token}\meta{tokens}\\
+% This macro checks the |\prefix@fam@key@default| macro. If the macro
+% has the form as defined by \pf{keyval} or \pf{xkeyval}, it is
+% possible to extract the default value and safe that (if requested)
+% and replace pointers. If the form is incorrect, just execute the
+% macro and forget about possible pointers. The reason for this check
+% is that certain packages (like \pf{fancyvrb}) abuse the `default
+% value system' to execute code instead of setting keys by redefining
+% default value macros. These macros do not actually contain a
+% default value and trying to extract that would not work.
+% \begin{macrocode}
+\def\XKV@default#1#2\@nil{%
+% \end{macrocode}
+% Retrieve the first token in the macro.
+% \begin{macrocode}
+ \expandafter\edef\expandafter\XKV@tempa
+ \expandafter{\expandafter\@gobble\string#1}%
+% \end{macrocode}
+% Construct the name that we expect on the basis of the \pf{keyval}
+% and \pf{xkeyval} syntax of default values.
+% \begin{macrocode}
+ \edef\XKV@tempb{\XKV@header\XKV@tkey}%
+% \end{macrocode}
+% Sanitize |\XKV@tempb| to reset catcodes for comparison with |\XKV@tempa|.
+% \begin{macrocode}
+ \@onelevel@sanitize\XKV@tempb
+ \ifx\XKV@tempa\XKV@tempb
+% \end{macrocode}
+% If it is safe, extract the value. We temporarily redefine the key
+% macro to save the default value in a macro. Saving the default value
+% itself directly to a macro when defining keys would of course be easier,
+% but a lot of packages rely on this system created by \pf{keyval}, so
+% we have to support it here.
+% \begin{macrocode}
+ \begingroup
+ \expandafter\def\csname\XKV@header\XKV@tkey\endcsname##1{%
+ \gdef\XKV@tempa{##1}%
+ }%
+ \csname\XKV@header\XKV@tkey @default\endcsname
+ \endgroup
+% \end{macrocode}
+% Save the default value to a value macro if either the key name has
+% been entered in a |\savekeys| macro or the starred form has been used.
+% \begin{macrocode}
+ \XKV@ifundefined{XKV@\XKV@header save}{}{%
+ \expandafter\XKV@testsavekey\csname XKV@\XKV@header
+ save\endcsname\XKV@tkey
+ }%
+ \ifXKV@rkv
+ \ifXKV@sg\expandafter\global\fi\expandafter\let
+ \csname XKV@\XKV@header\XKV@tkey @value\endcsname\XKV@tempa
+ \fi
+% \end{macrocode}
+% Replace the pointers.
+% \begin{macrocode}
+ \expandafter\XKV@replacepointers\expandafter
+ {\XKV@tempa}\XKV@afterelsefi
+% \end{macrocode}
+% Save internal state.
+% \begin{macrocode}
+ \XKV@srstate{@\romannumeral\XKV@depth}{}%
+% \end{macrocode}
+% Execute the key with the (possibly changed) default value.
+% \begin{macrocode}
+ \expandafter#1\expandafter{\XKV@tempa}\relax
+% \end{macrocode}
+% Restore internal state.
+% \begin{macrocode}
+ \XKV@srstate{}{@\romannumeral\XKV@depth}%
+ \else\XKV@afterfi
+% \end{macrocode}
+% Save internal state.
+% \begin{macrocode}
+ \XKV@srstate{@\romannumeral\XKV@depth}{}%
+% \end{macrocode}
+% Execute the key with the default value.
+% \begin{macrocode}
+ \csname\XKV@header\XKV@tkey @default\endcsname\relax
+% \end{macrocode}
+% Restore the state.
+% \begin{macrocode}
+ \XKV@srstate{}{@\romannumeral\XKV@depth}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\setrmkeys}
+% |*+|\oarg{prefix}\marg{families}\\
+% Set remaining keys stored in |\XKV@rm|. The starred version creates
+% a new list in |\XKV@rm| in case there are still keys that cannot
+% be located in the families specified. Care is taken again not to
+% expand fragile macros. Use |\XKV@testopa| again to handle optional
+% arguments.
+% \begin{macrocode}
+\def\setrmkeys{\XKV@testopta{\XKV@testoptc\XKV@setrmkeys}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@setrmkeys}
+% \oarg{na}\\
+% Submits the keys in |\XKV@rm| to |\XKV@setkeys|.
+% \begin{macrocode}
+\def\XKV@setrmkeys[#1]{%
+ \def\XKV@tempa{\XKV@setkeys[#1]}%
+ \expandafter\XKV@tempa\expandafter{\XKV@rm}%
+}
+% \end{macrocode}
+% \end{macro}
+% Reset catcodes.
+% \begin{macrocode}
+\XKVcatcodes
+%</xkvtex>
+% \end{macrocode}
+% \subsection{\texttt{xkeyval.sty}}
+% \changes{v1.5}{2004/09/27}{Made macros avoid expansions of options}
+% Initialize the package.
+% \begin{macrocode}
+%<*xkvlatex>
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{xkeyval}
+ [2005/08/12 v2.5d package option processing (HA)]
+% \end{macrocode}
+% Initializations. Load |xkeyval.tex|, adjust some catcodes to define
+% internal macros and initialize the |\DeclareOptionX*| working macro.
+% \begin{macrocode}
+\ifx\XKeyValLoaded\endinput\else\input xkeyval \fi
+\edef\XKVcatcodes{%
+ \catcode`\noexpand\=\the\catcode`\=\relax
+ \catcode`\noexpand\,\the\catcode`\,\relax
+ \let\noexpand\XKVcatcodes\relax
+}
+\catcode`\=12\relax
+\catcode`\,12\relax
+\let\XKV@doxs\relax
+% \end{macrocode}
+% \begin{macro}{\XKV@warn}
+% \begin{macro}{\XKV@err}
+% Warning and error macros.
+% \begin{macrocode}
+\def\XKV@warn#1{\PackageWarning{xkeyval}{#1}}
+\def\XKV@err#1{\PackageError{xkeyval}{#1}\@ehc}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% Retrieve the document class from |\@filelist|. This is the first
+% filename in the list with a class extension. Use a while loop to
+% scan the list and stop when we found the first filename which is
+% a class. Also stop in case the list is scanned fully.
+% \begin{macrocode}
+\XKV@whilist\@filelist\XKV@tempa\ifx\XKV@documentclass\@undefined\fi{%
+ \filename@parse\XKV@tempa
+ \ifx\filename@ext\@clsextension
+ \XKV@ifundefined{opt@\filename@area\filename@base.\filename@ext
+ }{}{%
+ \edef\XKV@documentclass{%
+ \filename@area\filename@base.\filename@ext
+ }%
+ }%
+ \fi
+}
+% \end{macrocode}
+% If we didn't find the document class, raise an error, otherwise
+% filter global options.
+% \begin{macrocode}
+\ifx\XKV@documentclass\@undefined
+ \XKV@err{xkeyval loaded before \protect\documentclass}%
+ \let\XKV@documentclass\@empty
+ \let\XKV@classoptionslist\@empty
+\else
+ \let\XKV@classoptionslist\@classoptionslist
+% \end{macrocode}
+% \changes{v1.4}{2004/08/24}{Fixed small bug in class option filtering}
+% Code to filter |key=value| pairs from |\@classoptionslist| without
+% expanding options.
+% \begin{macrocode}
+ \def\XKV@tempa#1{%
+ \let\@classoptionslist\@empty
+ \XKV@for@n{#1}\XKV@tempa{%
+ \expandafter\in@\expandafter=\expandafter{\XKV@tempa}%
+ \ifin@\else\XKV@addtolist@o\@classoptionslist\XKV@tempa\fi
+ }%
+ }
+ \expandafter\XKV@tempa\expandafter{\@classoptionslist}
+\fi
+% \end{macrocode}
+% \begin{macro}{\XKV@testopte}
+% \begin{macro}{\XKV@t@stopte}
+% \begin{macro}{\XKV@t@st@pte}
+% \changes{v1.9}{2005/01/16}{Added extension to default family}
+% \begin{macro}{\XKV@@t@st@pte}
+% \marg{function}\\
+% Macros for |\ExecuteOptionsX| and |\ProcessOptionsX| for testing for
+% optional arguments and inserting default values. Execute \meta{function}
+% after preforming the checks.
+% \begin{macrocode}
+\def\XKV@testopte#1{%
+ \XKV@ifstar{\XKV@sttrue\XKV@t@stopte#1}{\XKV@stfalse\XKV@t@stopte#1}%
+}
+\def\XKV@t@stopte#1{\@testopt{\XKV@t@st@pte#1}{KV}}
+\def\XKV@t@st@pte#1[#2]{%
+ \XKV@makepf{#2}%
+ \@ifnextchar<{\XKV@@t@st@pte#1}%
+ {\XKV@@t@st@pte#1<\@currname.\@currext>}%
+}
+\def\XKV@@t@st@pte#1<#2>{%
+ \XKV@sp@deflist\XKV@fams{#2}%
+ \@testopt#1{}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% Macros for class and package writers. These are mainly shortcuts to
+% |\define@key| and |\setkeys|. The \LaTeX\ macro |\@fileswith@pti@ns|
+% is set to generate an error. This is the case when a class or package
+% is loaded in between |\DeclareOptionX| and |\ProcessOptionsX| commands.
+% \begin{macro}{\DeclareOptionX}
+% |*|\\
+% Declare a package or class option.
+% \begin{macrocode}
+\def\DeclareOptionX{%
+ \let\@fileswith@pti@ns\@badrequireerror
+ \XKV@ifstar\XKV@dox\XKV@d@x
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@dox}
+% This macro defines |\XKV@doxs| to be used for unknown options.
+% \begin{macrocode}
+\long\def\XKV@dox#1{\XKV@toks{#1}\edef\XKV@doxs{\the\XKV@toks}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@d@x}
+% \begin{macro}{\XKV@@d@x}
+% \changes{v1.9}{2005/01/16}{Added extension to default family}
+% \begin{macro}{\XKV@@@d@x}
+% \changes{v1.1}{2004/04/30}{Redefined to insert an empty default value
+% if none is present}
+% Insert default prefix and family name (which is the filename of the
+% class or package) and add empty default value if none present. Execute
+% |\define@key|.
+% \begin{macrocode}
+\def\XKV@d@x{\@testopt\XKV@@d@x{KV}}
+\def\XKV@@d@x[#1]{%
+ \@ifnextchar<{\XKV@@@d@x[#1]}{\XKV@@@d@x[#1]<\@currname.\@currext>}%
+}
+\def\XKV@@@d@x[#1]<#2>#3{\@testopt{\define@key[#1]{#2}{#3}}{}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\ExecuteOptionsX}
+% \oarg{prefix}\marg{families}\oarg{na}\marg{key=value list}\\
+% This macro sets keys to specified values and uses |\XKV@setkeys| to do
+% the job. Insert default prefix and family name if none provided. Use
+% |\XKV@t@stopte| to handle optional arguments and reset |\ifXKV@st|
+% and |\ifXKV@pl| first to avoid unexpected behavior when |\setkeys*+|
+% (or a friend) has been used before |\ExecuteOptionsX|.
+% \begin{macrocode}
+\def\ExecuteOptionsX{\XKV@stfalse\XKV@plfalse\XKV@t@stopte\XKV@setkeys}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\ProcessOptionsX}
+% \changes{v1.4}{2004/08/24}{Fixed macro for \cs{LoadClass} case}
+% |*|\oarg{prefix}\marg{families}\\
+% Processes class or package using \pf{xkeyval}. The starred version
+% copies class options submitted by the user as well, given that they
+% are defined in the local families which are passed to the macro. Use
+% |\XKV@testopte| to handle optional arguments.
+% \begin{macrocode}
+\def\ProcessOptionsX{\XKV@plfalse\XKV@testopte\XKV@pox}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@pox}
+% \oarg{na}\\
+% Workhorse for |\ProcessOptionsX| and |\ProcessOptionsX*|.
+% \begin{macrocode}
+\def\XKV@pox[#1]{%
+ \let\XKV@tempa\@empty
+% \end{macrocode}
+% Set |\XKV@inpox|: indicates that we are in |\ProcessOptionsX| to
+% invoke a special routine in |\XKV@s@tkeys|.
+% \begin{macrocode}
+ \XKV@inpoxtrue
+% \end{macrocode}
+% Set |\@fileswith@pti@ns| again in case no |\DeclareOptionX| has been
+% used. This will be used to identify a call to |\setkeys| from
+% |\ProcessOptionsX|.
+% \begin{macrocode}
+ \let\@fileswith@pti@ns\@badrequireerror
+ \edef\XKV@testclass{\@currname.\@currext}%
+% \end{macrocode}
+% If \pf{xkeyval} is loaded by the document class, initialize
+% |\@unusedoptionlist|.
+% \begin{macrocode}
+ \ifx\XKV@testclass\XKV@documentclass
+ \let\@unusedoptionlist\XKV@classoptionslist
+ \XKV@ifundefined{ver@xkvltxp.sty}{}{%
+ \@onelevel@sanitize\@unusedoptionlist
+ }%
+ \else
+% \end{macrocode}
+% Else, if the starred version is used, copy global options in case
+% they are defined in local families. Do not execute this in the
+% document class to avoid setting keys twice.
+% \begin{macrocode}
+ \ifXKV@st
+ \def\XKV@tempb##1,{%
+ \def\CurrentOption{##1}%
+ \ifx\CurrentOption\@nnil\else
+ \XKV@g@tkeyname##1=\@nil\CurrentOption
+ \XKV@key@if@ndefined{\CurrentOption}{}{%
+% \end{macrocode}
+% If the option also exists in local families, add it to the list for
+% later use and remove it from |\@unusedoptionlist|.
+% \begin{macrocode}
+ \XKV@useoption{##1}%
+ \XKV@addtolist@n\XKV@tempa{##1}%
+ }%
+ \expandafter\XKV@tempb
+ \fi
+ }%
+ \expandafter\XKV@tempb\XKV@classoptionslist,\@nil,%
+ \fi
+ \fi
+% \end{macrocode}
+% Add current package options to the list.
+% \begin{macrocode}
+ \expandafter\XKV@addtolist@o\expandafter
+ \XKV@tempa\csname opt@\@currname.\@currext\endcsname
+% \end{macrocode}
+% Set options. We can be certain that global options can be set since
+% the definitions of local options have been checked above. Note that
+% |\DeclareOptionX*| will not consume global options when
+% |\ProcessOptionsX*| is used.
+% \begin{macrocode}
+ \def\XKV@tempb{\XKV@setkeys[#1]}%
+ \expandafter\XKV@tempb\expandafter{\XKV@tempa}%
+% \end{macrocode}
+% Reset the macro created by |\DeclareOptionX*| to avoid processing
+% future unknown keys using |\XKV@doxs|.
+% \begin{macrocode}
+ \let\XKV@doxs\relax
+% \end{macrocode}
+% Reset the |\XKV@rm| macro to avoid processing remaining options
+% with |\setrmkeys|.
+% \begin{macrocode}
+ \let\XKV@rm\@empty
+% \end{macrocode}
+% Reset |\ifXKV@inpox|: not in |\ProcessOptionsX| anymore.
+% \begin{macrocode}
+ \XKV@inpoxfalse
+% \end{macrocode}
+% Reset |\@fileswith@pti@ns| to allow loading of classes or packages
+% again.
+% \begin{macrocode}
+ \let\@fileswith@pti@ns\@@fileswith@pti@ns
+ \AtEndOfPackage{\let\@unprocessedoptions\relax}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKV@useoption}
+% \marg{option}\\
+% Removes an option from |\@unusedoptionlist|.
+% \begin{macrocode}
+\def\XKV@useoption#1{%
+ \def\XKV@resa{#1}%
+ \XKV@ifundefined{ver@xkvltxp.sty}{}{%
+ \@onelevel@sanitize\XKV@resa
+ }%
+ \@expandtwoargs\@removeelement{\XKV@resa}%
+ {\@unusedoptionlist}\@unusedoptionlist
+}
+% \end{macrocode}
+% \end{macro}
+% \changes{v1.3}{2004/05/09}{Moved the options section to the end of
+% the package to allow it to use \pf{xkeyval} option macros}
+% The options section. Postponed to the end to allow for using
+% \pf{xkeyval} options macros. All options are silently ignored.
+% \begin{macrocode}
+\DeclareOptionX*{%
+ \PackageWarning{xkeyval}{Unknown option `\CurrentOption'}%
+}
+\ProcessOptionsX
+% \end{macrocode}
+% Reset catcodes.
+% \begin{macrocode}
+\XKVcatcodes
+%</xkvlatex>
+% \end{macrocode}
+% \subsection{\texttt{keyval.tex}}
+% \changes{v1.4}{2004/08/24}{Added \pf{keyval} primitives}
+% Since the \pf{xkeyval} macros handle input in a very different way
+% than \pf{keyval} macros, it is not wise to redefine \pf{keyval}
+% primitives (like |\KV@do| and |\KV@split|) used by other packages
+% as a back door into |\setkeys|. Instead, we load the original
+% primitives here for compatibility to existing packages using (parts
+% of) \pf{keyval}. Most of the code is original, but slightly
+% adapted to \pf{xkeyval}. See the \pf{keyval} documentation for
+% information about the macros below.
+% \begin{macrocode}
+%<*xkvkeyval>
+%%
+%% Based on keyval.sty.
+%%
+\def\XKV@tempa#1{%
+\def\KV@@sp@def##1##2{%
+ \futurelet\XKV@resa\KV@@sp@d##2\@nil\@nil#1\@nil\relax##1}%
+\def\KV@@sp@d{%
+ \ifx\XKV@resa\@sptoken
+ \expandafter\KV@@sp@b
+ \else
+ \expandafter\KV@@sp@b\expandafter#1%
+ \fi}%
+\def\KV@@sp@b#1##1 \@nil{\KV@@sp@c##1}%
+ }
+\XKV@tempa{ }
+\def\KV@@sp@c#1\@nil#2\relax#3{\XKV@toks{#1}\edef#3{\the\XKV@toks}}
+\def\KV@do#1,{%
+ \ifx\relax#1\@empty\else
+ \KV@split#1==\relax
+ \expandafter\KV@do\fi}
+\def\KV@split#1=#2=#3\relax{%
+ \KV@@sp@def\XKV@tempa{#1}%
+ \ifx\XKV@tempa\@empty\else
+ \expandafter\let\expandafter\XKV@tempc
+ \csname\KV@prefix\XKV@tempa\endcsname
+ \ifx\XKV@tempc\relax
+ \XKV@err{`\XKV@tempa' undefined}%
+ \else
+ \ifx\@empty#3\@empty
+ \KV@default
+ \else
+ \KV@@sp@def\XKV@tempb{#2}%
+ \expandafter\XKV@tempc\expandafter{\XKV@tempb}\relax
+ \fi
+ \fi
+ \fi}
+\def\KV@default{%
+ \expandafter\let\expandafter\XKV@tempb
+ \csname\KV@prefix\XKV@tempa @default\endcsname
+ \ifx\XKV@tempb\relax
+ \XKV@err{No value specified for key `\XKV@tempa'}%
+ \else
+ \XKV@tempb\relax
+ \fi}
+%</xkvkeyval>
+% \end{macrocode}
+% \subsection{\texttt{xkvtxhdr.tex}}
+% This section generates |xkvtxhdr.tex| which contains some standard
+% \LaTeX\ macros taken from |latex.ltx|. This will only be loaded
+% when not using |xkeyval.sty|.
+% \begin{macrocode}
+%<*xkvheader>
+%%
+%% Taken from latex.ltx.
+%%
+\message{2005/02/22 v1.1 xkeyval TeX header (HA)}
+\def\@nnil{\@nil}
+\def\@empty{}
+\def\newif#1{%
+ \count@\escapechar \escapechar\m@ne
+ \let#1\iffalse
+ \@if#1\iftrue
+ \@if#1\iffalse
+ \escapechar\count@}
+\def\@if#1#2{%
+ \expandafter\def\csname\expandafter\@gobbletwo\string#1%
+ \expandafter\@gobbletwo\string#2\endcsname
+ {\let#1#2}}
+\long\def\@ifnextchar#1#2#3{%
+ \let\reserved@d=#1%
+ \def\reserved@a{#2}%
+ \def\reserved@b{#3}%
+ \futurelet\@let@token\@ifnch}
+\def\@ifnch{%
+ \ifx\@let@token\@sptoken
+ \let\reserved@c\@xifnch
+ \else
+ \ifx\@let@token\reserved@d
+ \let\reserved@c\reserved@a
+ \else
+ \let\reserved@c\reserved@b
+ \fi
+ \fi
+ \reserved@c}
+\def\:{\let\@sptoken= } \: % this makes \@sptoken a space token
+\def\:{\@xifnch} \expandafter\def\: {\futurelet\@let@token\@ifnch}
+\let\kernel@ifnextchar\@ifnextchar
+\long\def\@testopt#1#2{%
+ \kernel@ifnextchar[{#1}{#1[{#2}]}}
+\long\def\@firstofone#1{#1}
+\long\def \@gobble #1{}
+\long\def \@gobbletwo #1#2{}
+\def\@expandtwoargs#1#2#3{%
+\edef\reserved@a{\noexpand#1{#2}{#3}}\reserved@a}
+\edef\@backslashchar{\expandafter\@gobble\string\\}
+\newif\ifin@
+\def\in@#1#2{%
+ \def\in@@##1#1##2##3\in@@{%
+ \ifx\in@##2\in@false\else\in@true\fi}%
+ \in@@#2#1\in@\in@@}
+\def\strip@prefix#1>{}
+\def \@onelevel@sanitize #1{%
+ \edef #1{\expandafter\strip@prefix
+ \meaning #1}%
+}
+%</xkvheader>
+% \end{macrocode}
+% \subsection{\texttt{xkvview.sty}}
+% This section provides a small utility for package developers. It
+% provides several macros to generate overviews of the keys that are
+% defined in a package or a collection of packages. It is possible
+% to get an overview for a specific family, but also to get a complete
+% overview of all keys that have been defined after loading this
+% package.
+% \begin{macrocode}
+%<*xkvview>
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{xkvview}%
+ [2005/07/10 v1.4a viewer utility for xkeyval (HA)]
+\RequirePackage{xkeyval}
+\RequirePackage{longtable}
+\DeclareOptionX*{%
+ \PackageWarning{xkvview}{Unknown option `\CurrentOption'}%
+}
+\ProcessOptionsX
+% \end{macrocode}
+% Initializations.
+% \begin{macrocode}
+\newif\ifXKVV@vwkey
+\newif\ifXKVV@colii
+\newif\ifXKVV@coliii
+\newif\ifXKVV@coliv
+\newif\ifXKVV@colv
+\newwrite\XKVV@out
+\let\XKVV@db\@empty
+% \end{macrocode}
+% Setup options and presets.
+% \begin{macrocode}
+\define@cmdkeys[XKVV]{xkvview}[XKVV@]{%
+ prefix,family,type,default,file,columns,wcolsep,weol}[\@nil]
+\define@boolkeys[XKVV]{xkvview}[XKVV@]{view,vlabels,wlabels}[true]
+\presetkeys[XKVV]{xkvview}{prefix,family,type,default,file,%
+ columns,wcolsep=&,weol=\\,view,vlabels=false,wlabels=false}{}
+% \end{macrocode}
+% \begin{macro}{\XKVV@tabulate}
+% \begin{macro}{\XKVV@t@bulate}
+% \marg{key}\marg{type}\marg{default}\\
+% Adds the input information to the main database in |\XKVV@db|.
+% \begin{macrocode}
+\def\XKVV@tabulate#1#2#3{%
+ \def\XKV@tempa{#3}%
+ \@onelevel@sanitize\XKV@tempa
+ \XKV@addtolist@x\XKVV@db{#1=\expandafter
+ \XKVV@t@bulate\XKV@prefix=\XKV@tfam=#2=\XKV@tempa}%
+}
+\def\XKVV@t@bulate#1@{#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\XKV@define@key}
+% \begin{macro}{\XKV@d@fine@k@y}
+% \begin{macro}{\XKV@define@cmdkey}
+% \changes{v2.5c}{2005/07/10}{Avoid initializing control sequence as \cs{relax}}
+% \begin{macro}{\XKV@d@fine@ch@icekey}
+% \begin{macro}{\XKV@d@fine@ch@ic@key}
+% \begin{macro}{\XKV@d@f@ne@b@olkey}
+% Redefine the internals of key defining macros to record information
+% in the database.
+% \begin{macrocode}
+\def\XKV@define@key#1{%
+ \@ifnextchar[{\XKV@d@fine@k@y{#1}}{%
+ \XKVV@tabulate{#1}{ordinary}{[none]}%
+ \expandafter\def\csname\XKV@header#1\endcsname####1%
+ }%
+}
+\def\XKV@d@fine@k@y#1[#2]{%
+ \XKVV@tabulate{#1}{ordinary}{#2}%
+ \XKV@define@default{#1}{#2}%
+ \expandafter\def\csname\XKV@header#1\endcsname##1%
+}
+\def\XKV@define@cmdkey#1#2[#3]#4{%
+ \ifXKV@st
+ \XKVV@tabulate{#2}{command}{#3}%
+ \XKV@define@default{#2}{#3}%
+ \else
+ \XKVV@tabulate{#2}{command}{[none]}%
+ \fi
+ \def\XKV@tempa{\expandafter\def\csname\XKV@header#2\endcsname####1}%
+ \begingroup\expandafter\endgroup\expandafter\XKV@tempa\expandafter
+ {\expandafter\def\csname#1#2\endcsname{##1}#4}%
+}
+\def\XKV@d@fine@ch@icekey#1[#2]{%
+ \XKVV@tabulate{#1}{choice}{#2}%
+ \XKV@define@default{#1}{#2}%
+ \XKV@d@fine@ch@ic@key{#1}%
+}
+\def\XKV@d@fine@ch@ic@key#1{%
+ \XKVV@tabulate{#1}{choice}{[none]}%
+ \ifXKV@pl\XKV@afterelsefi
+ \expandafter\XKV@d@f@ne@ch@ic@k@y
+ \else\XKV@afterfi
+ \expandafter\XKV@d@f@ne@ch@ic@key
+ \fi
+ \csname\XKV@header#1\endcsname
+}
+\def\XKV@d@f@ne@b@olkey#1#2#3#4#5{%
+ \expandafter\newif\csname if#3\endcsname
+ \ifXKV@st
+ \XKVV@tabulate{#2}{boolean}{#4}%
+ \XKV@define@default{#2}{#4}%
+ \else
+ \XKVV@tabulate{#2}{boolean}{[none]}%
+ \fi
+ \ifXKV@pl
+ \def#1##1{\XKV@pltrue\XKV@sttrue
+ \XKV@checkchoice[\XKV@resa]{##1}{true,false}#5%
+ }%
+ \else
+ \def#1##1{\XKV@plfalse\XKV@sttrue
+ \XKV@checkchoice[\XKV@resa]{##1}{true,false}#5%
+ }%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\xkvview}
+% \marg{options}\\
+% The main macro. Produces a long table and/or writes to a target file.
+% \begin{macrocode}
+\def\xkvview#1{%
+% \end{macrocode}
+% Process all options.
+% \begin{macrocode}
+ \setkeys[XKVV]{xkvview}{#1}%
+ \ifx\XKVV@default\@nnil\else\@onelevel@sanitize\XKVV@default\fi
+% \end{macrocode}
+% If no column information, display all columns.
+% \begin{macrocode}
+ \ifx\XKVV@columns\@nnil
+ \count@5
+ \XKVV@coliitrue\XKVV@coliiitrue\XKVV@colivtrue\XKVV@colvtrue
+ \else
+% \end{macrocode}
+% Check how much and which columns should be displayed.
+% \begin{macrocode}
+ \count@\@ne
+ \@expandtwoargs\in@{,prefix,}{,\XKVV@columns,}%
+ \ifin@\advance\count@\@ne\XKVV@coliitrue\else\XKVV@coliifalse\fi
+ \@expandtwoargs\in@{,family,}{,\XKVV@columns,}%
+ \ifin@\advance\count@\@ne\XKVV@coliiitrue\else\XKVV@coliiifalse\fi
+ \@expandtwoargs\in@{,type,}{,\XKVV@columns,}%
+ \ifin@\advance\count@\@ne\XKVV@colivtrue\else\XKVV@colivfalse\fi
+ \@expandtwoargs\in@{,default,}{,\XKVV@columns,}%
+ \ifin@\advance\count@\@ne\XKVV@colvtrue\else\XKVV@colvfalse\fi
+ \fi
+ \ifXKVV@view
+% \end{macrocode}
+% Construct long table header.
+% \begin{macrocode}
+ \protected@edef\XKV@tempa{\noexpand\begin{longtable}[l]{%
+ *\the\count@ l}\normalfont Key\ifXKVV@colii&\normalfont Prefix%
+ \fi\ifXKVV@coliii&\normalfont Family\fi\ifXKVV@coliv&\normalfont
+ Type\fi\ifXKVV@colv&\normalfont Default\fi\\\noexpand\hline
+ \noexpand\endfirsthead\noexpand\multicolumn{\the\count@}{l}{%
+ \normalfont\emph{Continued from previous page}}\\\noexpand\hline
+ \normalfont Key\ifXKVV@colii&\normalfont Prefix\fi\ifXKVV@coliii
+ &\normalfont Family\fi\ifXKVV@coliv&\normalfont Type\fi
+ \ifXKVV@colv&\normalfont Default\fi\\\noexpand\hline\noexpand
+ \endhead\noexpand\hline\noexpand\multicolumn{\the\count@}{r}{%
+ \normalfont\emph{Continued on next page}}\\\noexpand\endfoot
+ \noexpand\hline\noexpand\endlastfoot
+ }%
+ \XKV@toks\expandafter{\XKV@tempa}%
+ \fi
+% \end{macrocode}
+% Open the target file for writing if a file name has been specified.
+% \begin{macrocode}
+ \ifx\XKVV@file\@nnil\else\immediate\openout\XKVV@out\XKVV@file\fi
+% \end{macrocode}
+% Parse the entire database to find entries that match the criteria.
+% \begin{macrocode}
+ \XKV@for@o\XKVV@db\XKV@tempa{%
+ \XKVV@vwkeytrue\expandafter\XKVV@xkvview\XKV@tempa\@nil
+ }%
+% \end{macrocode}
+% Finish the long table and typeset it.
+% \begin{macrocode}
+ \ifXKVV@view
+ \addto@hook\XKV@toks{\end{longtable}}%
+ \begingroup\ttfamily\the\XKV@toks\endgroup
+ \fi
+% \end{macrocode}
+% Close the target file.
+% \begin{macrocode}
+ \ifx\XKVV@file\@nnil\else\immediate\closeout\XKVV@out\fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XKVV@xkvview}
+% \meta{key}|=|\meta{prefix}|=|\meta{family}|=|\meta{type}|=|\meta{default}|\@nil|\\
+% Parse a row in the database to get individual column entries. Select
+% the requested columns and store the table row in the token or write
+% it to the target file.
+% \begin{macrocode}
+\def\XKVV@xkvview#1=#2=#3=#4=#5\@nil{%
+% \end{macrocode}
+% Check whether the current entry satisfies all criteria.
+% \begin{macrocode}
+ \ifx\XKVV@prefix\@nnil\else
+ \def\XKV@tempa{#2}%
+ \ifx\XKV@tempa\XKVV@prefix\else\XKVV@vwkeyfalse\fi
+ \fi
+ \ifx\XKVV@family\@nnil\else
+ \def\XKV@tempa{#3}%
+ \ifx\XKV@tempa\XKVV@family\else\XKVV@vwkeyfalse\fi
+ \fi
+ \ifx\XKVV@type\@nnil\else
+ \def\XKV@tempa{#4}%
+ \ifx\XKV@tempa\XKVV@type\else\XKVV@vwkeyfalse\fi
+ \fi
+ \ifx\XKVV@default\@nnil\else
+ \def\XKV@tempa{#5}%
+ \ifx\XKV@tempa\XKVV@default\else\XKVV@vwkeyfalse\fi
+ \fi
+ \ifXKVV@vwkey
+% \end{macrocode}
+% If output should go to the dvi, construct the table row and add it
+% to the token.
+% \begin{macrocode}
+ \ifXKVV@view
+ \edef\XKV@tempa{%
+ #1\ifXKVV@colii&#2\fi\ifXKVV@coliii&#3\fi
+ \ifXKVV@coliv&#4\fi\ifXKVV@colv&#5\fi
+ \ifXKVV@vlabels\noexpand\label{#2-#3-#1}\fi
+ }%
+ \expandafter\addto@hook\expandafter
+ \XKV@toks\expandafter{\XKV@tempa\\}%
+ \fi
+ \ifx\XKVV@file\@nnil\else
+% \end{macrocode}
+% When writing, construct the line and write it to file. Notice that
+% \pf{xkeyval} removes braces and spaces, so |wcolsep={ }| won't make
+% a space between column entries, but |wcolsep=\space| will.
+% \begin{macrocode}
+ \immediate\write\XKVV@out{%
+ #1\ifXKVV@colii\XKVV@wcolsep#2\fi
+ \ifXKVV@coliii\XKVV@wcolsep#3\fi
+ \ifXKVV@coliv\XKVV@wcolsep#4\fi
+ \ifXKVV@colv\XKVV@wcolsep#5\fi
+ \ifXKVV@wlabels\string\label{#2-#3-#1}\fi
+ \expandafter\noexpand\XKVV@weol
+ }%
+ \fi
+ \fi
+}
+%</xkvview>
+% \end{macrocode}
+% \end{macro}
+% \subsection{\texttt{xkvltxp.sty}}\label{sec:ltxpatch}
+% \changes{v1.5}{2004/09/27}{Added \LaTeX\ kernel patch}
+% This section redefines some kernel macros as to avoid expansions of
+% options at several places to allow for macros in key values in class
+% and package options. It uses a temporary token register and some
+% careful expansions. Notice that |\@unusedoptionlist| is sanitized
+% after creation by \pf{xkeyval} to avoid |\@removeelement| causing
+% problems with macros and braces. See for more information about the
+% original versions of the macros below the kernel source documentation
+% \cite{LaTeXbase}.
+% \begin{macrocode}
+%<*xkvltxpatch>
+%%
+%% Based on latex.ltx.
+%%
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{xkvltxp}[2004/12/13 v1.2 LaTeX2e kernel patch (HA)]
+\def\@pass@ptions#1#2#3{%
+ \def\reserved@a{#2}%
+ \def\reserved@b{\CurrentOption}%
+ \ifx\reserved@a\reserved@b
+ \@ifundefined{opt@#3.#1}{\@temptokena\expandafter{#2}}{%
+ \@temptokena\expandafter\expandafter\expandafter
+ {\csname opt@#3.#1\endcsname}%
+ \@temptokena\expandafter\expandafter\expandafter{%
+ \expandafter\the\expandafter\@temptokena\expandafter,#2}%
+ }%
+ \else
+ \@ifundefined{opt@#3.#1}{\@temptokena{#2}}{%
+ \@temptokena\expandafter\expandafter\expandafter
+ {\csname opt@#3.#1\endcsname}%
+ \@temptokena\expandafter{\the\@temptokena,#2}%
+ }%
+ \fi
+ \expandafter\xdef\csname opt@#3.#1\endcsname{\the\@temptokena}%
+}
+\def\OptionNotUsed{%
+ \ifx\@currext\@clsextension
+ \let\reserved@a\CurrentOption
+ \@onelevel@sanitize\reserved@a
+ \xdef\@unusedoptionlist{%
+ \ifx\@unusedoptionlist\@empty\else\@unusedoptionlist,\fi
+ \reserved@a}%
+ \fi
+}
+\def\@use@ption{%
+ \let\reserved@a\CurrentOption
+ \@onelevel@sanitize\reserved@a
+ \@expandtwoargs\@removeelement\reserved@a
+ \@unusedoptionlist\@unusedoptionlist
+ \csname ds@\CurrentOption\endcsname
+}
+\def\@fileswith@pti@ns#1[#2]#3[#4]{%
+ \ifx#1\@clsextension
+ \ifx\@classoptionslist\relax
+ \@temptokena{#2}%
+ \xdef\@classoptionslist{\the\@temptokena}%
+ \def\reserved@a{%
+ \@onefilewithoptions#3[#2][#4]#1%
+ \@documentclasshook}%
+ \else
+ \def\reserved@a{%
+ \@onefilewithoptions#3[#2][#4]#1}%
+ \fi
+ \else
+ \@temptokena{#2}%
+ \def\reserved@b##1,{%
+ \ifx\@nil##1\relax\else
+ \ifx\relax##1\relax\else
+ \noexpand\@onefilewithoptions##1%
+ [\the\@temptokena][#4]\noexpand\@pkgextension
+ \fi
+ \expandafter\reserved@b
+ \fi}%
+ \edef\reserved@a{\zap@space#3 \@empty}%
+ \edef\reserved@a{\expandafter\reserved@b\reserved@a,\@nil,}%
+ \fi
+ \reserved@a}
+\let\@@fileswith@pti@ns\@fileswith@pti@ns
+%</xkvltxpatch>
+% \end{macrocode}
+% \subsection{\texttt{pst-xkey.tex}}
+% Avoid loading |pst-xkey.tex| twice.
+% \begin{macrocode}
+%<*pxktex>
+\csname PSTXKeyLoaded\endcsname
+\let\PSTXKeyLoaded\endinput
+\edef\PSTXKeyCatcodes{%
+ \catcode`\noexpand\@\the\catcode`\@\relax
+ \let\noexpand\PSTXKeyCatcodes\relax
+}
+\catcode`\@=11\relax
+% \end{macrocode}
+% Load \pf{xkeyval} when not already done by |pst-xkey.sty| and
+% provide information.
+% \begin{macrocode}
+\ifx\ProvidesFile\@undefined
+ \message{2005/02/22 v1.5 PSTricks specialization of xkeyval (HA)}
+ \ifx\XKeyValLoaded\endinput\else\input xkeyval \fi
+\else
+ \ProvidesFile{pst-xkey.tex}
+ [2005/02/22 v1.5 PSTricks specialization of xkeyval (HA)]
+ \@addtofilelist{pst-xkey.tex}
+ \RequirePackage{xkeyval}
+\fi
+% \end{macrocode}
+% \begin{macro}{\pst@famlist}
+% Initialize the list of families.
+% \begin{macrocode}
+\def\pst@famlist{}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\pst@addfams}
+% Adds the family to |\pst@famlist| if it was not in yet.
+% \begin{macrocode}
+\def\pst@addfams#1{%
+ \XKV@for@n{#1}\XKV@tempa{%
+ \@expandtwoargs\in@{,\XKV@tempa,}{,\pst@famlist,}%
+ \ifin@\else\edef\pst@famlist{\pst@famlist,\XKV@tempa}\fi
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\psset}
+% \changes{v1.8b}{2004/12/22}{Properly expand \cs{pst@famlist}}
+% \begin{macro}{\pss@t}
+% Set keys. Uses \pf{xkeyval}'s |\setkeys+|.
+% \begin{macrocode}
+\def\psset{%
+ \expandafter\@testopt\expandafter\pss@t\expandafter{\pst@famlist}%
+}
+\def\pss@t[#1]{\setkeys+[psset]{#1}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\@psset}
+% This macro defined by |pstricks.tex| is internally used as a
+% shortcut. We have to redefine this as well to avoid problems.
+% \begin{macrocode}
+\def\@psset#1,\@nil{%
+ \edef\XKV@tempa{\noexpand\setkeys+[psset]{\pst@famlist}}%
+ \XKV@tempa{#1}%
+}
+% \end{macrocode}
+% \end{macro}
+% Finalize.
+% \begin{macrocode}
+\PSTXKeyCatcodes
+%</pxktex>
+% \end{macrocode}
+% \subsection{\texttt{pst-xkey.sty}}
+% Initialize the package.
+% \begin{macrocode}
+%<*pxklatex>
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{pst-xkey}
+ [2005/02/22 v1.5 package wrapper for pst-xkey.tex (HA)]
+% \end{macrocode}
+% Load required package.
+% \begin{macrocode}
+\ifx\PSTXKeyLoaded\endinput\else\input pst-xkey \fi
+% \end{macrocode}
+% Ignore options.
+% \begin{macrocode}
+\DeclareOptionX*{%
+ \PackageWarning{pst-xkey}{Unknown option `\CurrentOption'}%
+}
+\ProcessOptionsX
+%</pxklatex>
+% \end{macrocode}
+%
+% \Finale
+% \endinput
+%
+%<*xkvex1>
+\input xkeyval
+
+\catcode`\@=11
+
+%% xkeyval package: TeX example
+%% Hendri Adriaens
+
+\noindent Example 1. This example demonstrates the use of the new
+macros for setting keys of the `xkeyval' package. Have a look at the
+source for information about this example and to understand the output.
+
+%% Define keys.
+\define@key{fami}{keyi}{key 1: #1 }
+\define@key{famii}{keyii}{key 2: #1 }
+\define@key{famiii}{keyiii}[test 2]{key 3: #1 }
+\define@key{famiv}{keyi}{key 4: #1 }
+
+%% Set keys from multiple families.
+\setkeys{fami,famii,famiii}{keyi=test 1,keyiii}
+
+%% Multiplely defined keys will be taken from the first family on the
+%% list that defines the key. When + is used, all families
+%% defining the key will set it.
+\setkeys{fami,famiv}{keyi=test 3}\par
+\setkeys{famiv,fami}{keyi=test 4}\par
+\setkeys+{fami,famiv}{keyi=test 5}\par
+
+%% Starred form sets keys that it can find in the families specified.
+%% Keys that cannot be located will be put onto a list for later use
+%% by \setrmkeys.
+\setkeys*{famiv}{keyi=test 9,keyii=http://www.test10.com,
+ keyiii=test 11}\par
+
+%% Try to set the remaining keys from the previous step. The starred
+%% version defines a new list in case there are still keys that cannot
+%% be located in the given families. The command below does not do
+%% anything since the `keyi' key has already been taken from family
+%% `famiv' above.
+\setrmkeys*{fami}\par
+
+%% The normal version will complain (as \setkeys) when it cannot locate
+%% a key which was previously submitted to \xsetkeys and hasn't been
+%% set yet by previous commands. `xkeyval' commands can also be used to
+%% set `keyval' options.
+\setrmkeys{famii,famiii}\par
+
+%% Set keys, excluding some keys.
+\setkeys{fami,famii,famiii}[keyi,keyiii]{keyi=test 6,keyii=test
+7,keyiii=test 8}\par
+
+%% Test whether a key is defined in a family from the list.
+\key@ifundefined{fami,famii}{keyiii}
+{keyiii is not defined in family `fami' or `famii'}
+{keyiii is defined in family `fami' or `famii'}
+
+%% Define some keys and macros.
+\define@cmdkey[my]{fama}[my@]{keya}[none]{}
+\define@choicekey[my]{fama}{keyb}{a,b,c}[b]{correct input: #1}
+\define@boolkey[my]{famb}{keyc}[true]{}
+\def\testa{\setkeys[my]{fama}}
+\def\testb{\setkeys[my]{famb}}
+\def\testset{\setkeys[my]{fama,famb}}
+
+%% Now \testa can only set keya, \testb can only
+%% set keyb and \testset can set both.
+\testa{keya}
+ \my@keya\
+\testa{keyb}
+\testb{keyc}
+ \ifmy@famb@keyc true \else false \fi
+\testset{keya=test 11,keyb=c,keyc=false}
+ \my@keya\space
+ \ifmy@famb@keyc true \else false \fi
+
+%% Pointer system
+
+%% First we (re)define some keys.
+\define@key{fam}{keyi}{key 1: #1 }
+\define@key{fam}{keyii}{key 2: #1 }
+\define@key{fam}{keyiii}[test 2]{key 3: #1 }
+
+%% Pointers can be used to copy the value of other keys in the same
+%% family. This can be done in two ways. The first example shows `on
+%% the spot' value saving.
+\setkeys{fam}{\savevalue{keyi}=test 12,\savevalue{keyii}=\usevalue{keyi}}
+\setkeys{fam}{keyiii=\usevalue{keyii}}
+
+%% However, you can also predefine the keys to be saved for the entire
+%% document with a single command.
+\savekeys{fam}{keyi,keyii}
+\setkeys{fam}{keyi=test 13,keyii=\usevalue{keyi}}
+\setkeys{fam}{keyiii=\usevalue{keyii}}
+
+%% Pointers can be used in default values as well. Remember that the
+%% previous example used \savekeys for keyi and keyii.
+\define@key{fam}{keyi}{keyi: #1 }
+\define@key{fam}{keyii}[\usevalue{keyi}]{keyii: #1 }
+\define@key{fam}{keyiii}[\usevalue{keyii}]{keyiii: #1 }
+\setkeys{fam}{keyi=test 14}
+\setkeys{fam}{keyii}
+\setkeys{fam}{keyiii}
+
+%% Presetting keys
+
+%% Simple example of the preset system.
+\define@key{fam}{keyi}{keyi: #1 }
+\define@key{fam}{keyii}{keyii: #1 }
+\presetkeys{fam}{keyi=blue}{keyii=\usevalue{keyi}}
+\setkeys{fam}{}\par
+\setkeys{fam}{keyi=red}\par
+\setkeys{fam}{keyii=red}
+\presetkeys{fam}{keyi=red}{}\par
+\setkeys{fam}{keyii=\usevalue{keyi}}
+
+\bye
+%</xkvex1>
+%
+%<*xkvex2>
+\documentclass{article}
+\usepackage{xkeyval}
+\usepackage{xcolor,calc}
+
+%% Example of setting keyval options using xkeyval
+\usepackage{hyperref}
+\usepackage{helvet}
+\setkeys{Hyp,Hel}{colorlinks,urlcolor=green,scaled=.85}
+
+\title{\textsf{xkeyval} package\\\normalsize\emph{Example 2}}
+\author{Hendri Adriaens}
+\setlength{\parindent}{0cm}
+
+\makeatletter
+
+\begin{document}
+\maketitle
+
+This example demonstrates the use of the new macros for setting
+keys of the \textsf{xkeyval} package. Below each piece of verbatim
+code, you can find its output.
+
+\section{Simple operations}
+
+Define keys.
+\begin{verbatim}
+\define@key{fami}{keyi}{key 1: #1\space}
+\define@key{famii}{keyii}{key 2: #1\space}
+\define@key{famiii}{keyiii}[test 2]{key 3: #1\space}
+\define@key{famiv}{keyi}{key 4: #1\space}
+\end{verbatim}
+\define@key{fami}{keyi}{key 1: #1\space}
+\define@key{famii}{keyii}{key 2: #1\space}
+\define@key{famiii}{keyiii}[test 2]{key 3: #1\space}
+\define@key{famiv}{keyi}{key 4: #1\space}
+
+Set keys from multiple families.
+\begin{verbatim}
+\setkeys{fami,famii,famiii}{keyi=test 1,keyiii}
+\end{verbatim}
+\begin{itemize}
+\item[$\Rightarrow$]
+\setkeys{fami,famii,famiii}{keyi=test 1,keyiii}
+\end{itemize}
+
+Multiplely defined keys will be taken from the first family on the
+list that defines the key. When \verb|+| is used, all families
+defining the key will set it.
+\begin{verbatim}
+\setkeys{fami,famiv}{keyi=test 3}
+\setkeys{famiv,fami}{keyi=test 4}
+\setkeys+{fami,famiv}{keyi=test 5}
+\end{verbatim}
+\begin{itemize}
+\item[$\Rightarrow$]
+\setkeys{fami,famiv}{keyi=test 3}\par
+\setkeys{famiv,fami}{keyi=test 4}\par
+\setkeys+{fami,famiv}{keyi=test 5}
+\end{itemize}
+
+Starred form sets keys that it can find in the families specified.
+Keys that cannot be located will be put onto a list for later use
+by \verb+\setrmkeys+.
+\begin{verbatim}
+\setkeys*{famiv}{keyi=test 9,keyii=\url{http://www.test10.com},
+ keyiii=this key has been set on page \thepage}
+\end{verbatim}
+\begin{itemize}
+\item[$\Rightarrow$]
+\setkeys*{famiv}{keyi=test 9,keyii=\url{http://www.test10.com},
+ keyiii=this key has been set on page \thepage}
+\end{itemize}
+
+Try to set the remaining keys from the previous step. The starred
+version defines a new list in case there are still keys that
+cannot be located in the given families. The command below does
+not do anything since the \verb+keyi+ key has already been taken
+from family \verb+famiv+ above.
+\begin{verbatim}
+\setrmkeys*{fami}
+\end{verbatim}
+\setrmkeys*{fami}\par
+
+The normal version will complain (as \verb+\setkeys+) when it
+cannot locate a key which was previously submitted to
+\verb+\setkeys+ and hasn't been set yet by previous commands.
+\textsf{xkeyval} commands can also be used to set \textsf{keyval}
+options as is done to the color of the url created with the
+\textsf{hyperref} package and the scaling of the font used for
+`\textsf{xkeyval}' with the \textsf{helvet} package. (See the
+preamble of the example for the code).
+\begin{verbatim}
+\setrmkeys{famii,famiii}
+\end{verbatim}
+\begin{itemize}
+\item[$\Rightarrow$]
+\setrmkeys{famii,famiii}
+\end{itemize}
+
+Set keys, excluding some keys.
+\begin{verbatim}
+\setkeys{fami,famii,famiii}[keyi,keyiii]{keyi=test 6,keyii=test 7,keyiii=test 8}
+\end{verbatim}
+\begin{itemize}
+\item[$\Rightarrow$]
+\setkeys{fami,famii,famiii}[keyi,keyiii]{keyi=test 6,keyii=test 7,keyiii=test 8}
+\end{itemize}
+
+Test whether a key is defined in a family from the list.
+\begin{verbatim}
+\key@ifundefined{fami,famii}{keyiii}
+{keyiii is not defined in family `fami' or `famii'}
+{keyiii is defined in family `fami' or `famii'}
+\end{verbatim}
+\begin{itemize}
+\item[$\Rightarrow$]
+\key@ifundefined{fami,famii}{keyiii}
+{keyiii is not defined in family `fami' or `famii'}
+{keyiii is defined in family `fami' or `famii'}
+\end{itemize}
+
+Define some keys and macros.
+\begin{verbatim}
+\define@cmdkey[my]{fama}[my@]{keya}[none]{}
+\define@choicekey[my]{fama}{keyb}{a,b,c}[b]{correct input: #1}
+\define@boolkey[my]{famb}{keyc}[true]{}
+\def\testa{\setkeys[my]{fama}}
+\def\testb{\setkeys[my]{famb}}
+\def\testset{\setkeys[my]{fama,famb}}
+\end{verbatim}
+\define@cmdkey[my]{fama}[my@]{keya}[none]{}
+\define@choicekey[my]{fama}{keyb}{a,b,c}[b]{correct input: #1}
+\define@boolkey[my]{famb}{keyc}[true]{}
+\def\testa{\setkeys[my]{fama}}
+\def\testb{\setkeys[my]{famb}}
+\def\testset{\setkeys[my]{fama,famb}}
+Now \verb+\testa+ can only set \verb+keya+, \verb+\testb+ can only
+set \verb+keyb+ and \verb+\testset+ can set both.
+\begin{verbatim}
+\testa{keya}
+ \my@keya\
+\testa{keyb}
+\testb{keyc}
+ \ifmy@famb@keyc true \else false \fi
+\testset{keya=test 11,keyb=c,keyc=false}
+ \my@keya\space
+ \ifmy@famb@keyc true \else false \fi
+\end{verbatim}
+\begin{itemize}
+\item[$\Rightarrow$]
+\testa{keya}
+ \my@keya\
+\testa{keyb}
+\testb{keyc}
+ \ifmy@famb@keyc true \else false \fi
+\testset{keya=test 11,keyb=c,keyc=false}
+ \my@keya\space
+ \ifmy@famb@keyc true \else false \fi
+\end{itemize}
+
+\section{Pointers and values}
+
+First we (re)define some keys.
+\begin{verbatim}
+\define@key{fam}{keyi}{key 1: #1 }
+\define@key{fam}{keyii}{key 2: #1 }
+\define@key{fam}{keyiii}[test 2]{key 3: #1 }
+\end{verbatim}
+\define@key{fam}{keyi}{key 1: #1 }
+\define@key{fam}{keyii}{key 2: #1 }
+\define@key{fam}{keyiii}[test 2]{key 3: #1 }
+
+Pointers can be used to copy the value of other keys in the same
+family. This can be done in two ways. The first example shows `on
+the spot' value saving.
+\begin{verbatim}
+\setkeys{fam}{\savevalue{keyi}=test 12,\savevalue{keyii}=\usevalue{keyi}}
+\setkeys{fam}{keyiii=\usevalue{keyii}}
+\end{verbatim}
+\begin{itemize}
+\item[$\Rightarrow$]
+\setkeys{fam}{\savevalue{keyi}=test 12,\savevalue{keyii}=\usevalue{keyi}}
+\setkeys{fam}{keyiii=\usevalue{keyii}}
+\end{itemize}
+
+However, you can also predefine the keys to be saved for the entire
+document with a single command. Note that we force keys to be saved
+globally. This is necessary here since the commands in the source of
+this document appear in an environment.
+\begin{verbatim}
+\savekeys{fam}{\global{keyi},\global{keyii}}
+\setkeys{fam}{keyi=test 13,keyii=\usevalue{keyi}}
+\setkeys{fam}{keyiii=\usevalue{keyii}}
+\end{verbatim}
+\begin{itemize}
+\item[$\Rightarrow$]
+\savekeys{fam}{\global{keyi},\global{keyii}}
+\setkeys{fam}{keyi=test 13,keyii=\usevalue{keyi}}
+\setkeys{fam}{keyiii=\usevalue{keyii}}
+\end{itemize}
+
+Pointers can be used in default values as well. Remember that the
+previous example used \verb+\savekeys+ for \verb+keyi+ and \verb+keyii+.
+\begin{verbatim}
+\define@key{fam}{keyi}{keyi: #1 }
+\define@key{fam}{keyii}[\usevalue{keyi}]{keyii: #1 }
+\define@key{fam}{keyiii}[\usevalue{keyii}]{keyiii: #1 }
+\setkeys{fam}{keyi=test 14}
+\setkeys{fam}{keyii}
+\setkeys{fam}{keyiii}
+\end{verbatim}
+\begin{itemize}
+\item[$\Rightarrow$]
+\define@key{fam}{keyi}{keyi: #1 }
+\define@key{fam}{keyii}[\usevalue{keyi}]{keyii: #1 }
+\define@key{fam}{keyiii}[\usevalue{keyii}]{keyiii: #1 }
+\setkeys{fam}{keyi=test 14}
+\setkeys{fam}{keyii}
+\setkeys{fam}{keyiii}
+\end{itemize}
+
+\section{Presetting keys}
+
+Simple example of the preset system.
+\begin{verbatim}
+\define@key{fam}{keyi}{keyi: #1 }
+\define@key{fam}{keyii}{keyii: #1 }
+\presetkeys{fam}{keyi=blue}{keyii=\usevalue{keyi}}
+\setkeys{fam}{}\par
+\setkeys{fam}{keyi=red}\par
+\setkeys{fam}{keyii=red}
+\presetkeys{fam}{keyi=red}{}
+\setkeys{fam}{keyii=\usevalue{keyi}}
+\end{verbatim}
+\begin{itemize}
+\item[$\Rightarrow$]
+\define@key{fam}{keyi}{keyi: #1 }
+\define@key{fam}{keyii}{keyii: #1 }
+\presetkeys{fam}{keyi=blue}{keyii=\usevalue{keyi}}
+\setkeys{fam}{}\par
+\setkeys{fam}{keyi=red}\par
+\setkeys{fam}{keyii=red}
+\presetkeys{fam}{keyi=red}{}\par
+\setkeys{fam}{keyii=\usevalue{keyi}}
+\end{itemize}
+
+\section{Application of pointers, values and presets}
+
+\setkeys{Hyp}{urlcolor=black}
+More complicated example of the preset
+system and pointer system. See for more information about this
+example the
+\textsf{xkeyval} article on\par
+\url{http://stuwww.uvt.nl/~hendri/downloads/xkeyval.html}.
+\begin{verbatim}
+\newdimen\shadowsize
+\define@boolkey{Fbox}{frame}[true]{}
+\define@boolkey{Fbox}{shadow}[true]{}
+\define@key{Fbox}{framecolor}{\def\Fboxframecolor{#1}}
+\define@key{Fbox}{shadowcolor}{\def\Fboxshadowcolor{#1}}
+\define@key{Fbox}{framesize}{\setlength\fboxrule{#1}}
+\define@key{Fbox}{shadowsize}{\setlength\shadowsize{#1}}
+\presetkeys{Fbox}{frame,framecolor=red,framesize=0.5pt}%
+ {shadow=\usevalue{frame},shadowcolor=\usevalue{framecolor}!40,%
+ shadowsize=\usevalue{framesize}*4}
+\savekeys{Fbox}{frame,framecolor,framesize}
+\newcommand*\Fbox[2][]{%
+ \setkeys{Fbox}{#1}%
+ {\ifKV@Fbox@frame\else\fboxrule0pt\fi
+ \ifKV@Fbox@shadow\else\shadowsize0pt\fi
+ \sbox0{\fcolorbox{\Fboxframecolor}{white}{#2}}%
+ \hskip\shadowsize
+ \color{\Fboxshadowcolor}%
+ \rule[-\dp0]{\wd0}{\ht0+\dp0}%
+ \llap{\raisebox{\shadowsize}%
+ {\box0\hskip\shadowsize}}}%
+}
+\Fbox{demo1}
+\Fbox[framecolor=blue]{demo2}
+\Fbox[shadow=false]{demo3}
+\Fbox[framesize=1pt]{demo4}
+\Fbox[frame=false,shadow]{demo5}
+\end{verbatim}
+\newdimen\shadowsize
+\define@boolkey{Fbox}{frame}[true]{}
+\define@boolkey{Fbox}{shadow}[true]{}
+\define@key{Fbox}{framecolor}%
+ {\def\Fboxframecolor{#1}}
+\define@key{Fbox}{shadowcolor}%
+ {\def\Fboxshadowcolor{#1}}
+\define@key{Fbox}{framesize}%
+ {\setlength\fboxrule{#1}}
+\define@key{Fbox}{shadowsize}%
+ {\setlength\shadowsize{#1}}
+\presetkeys{Fbox}%
+ {frame,framecolor=red,framesize=0.5pt}%
+ {shadow=\usevalue{frame},
+ shadowcolor=\usevalue{framecolor}!40,
+ shadowsize=\usevalue{framesize}*4}
+\savekeys{Fbox}{frame,framecolor,framesize}
+\newcommand*\Fbox[2][]{%
+ \setkeys{Fbox}{#1}%
+ {\ifKV@Fbox@frame\else\fboxrule0pt\fi
+ \ifKV@Fbox@shadow\else\shadowsize0pt\fi
+ \sbox0{\fcolorbox{\Fboxframecolor}{white}{#2}}%
+ \hskip\shadowsize
+ \color{\Fboxshadowcolor}%
+ \rule[-\dp0]{\wd0}{\ht0+\dp0}%
+ \llap{\raisebox{\shadowsize}%
+ {\box0\hskip\shadowsize}}}%
+}
+\Fbox{demo1}
+\Fbox[framecolor=blue]{demo2}
+\Fbox[shadow=false]{demo3}
+\Fbox[framesize=1pt]{demo4}
+\Fbox[frame=false,shadow]{demo5}
+
+\end{document}
+%</xkvex2>
+%
+%<*xkvex3>
+%% keyi will set \keyi in xkveca.cls
+%% keyvi will set \keyvi in xkveca.cls and xkvesc.sty will pick
+%% it up from \documentclass and redefine it
+%% IgnoredGlobal and another=key will be considered as global
+%% options to be passed on to packages. Not used anymore.
+\documentclass[keyi=test1,keyvi,another=key,IgnoredGlobal,10pt]{xkveca}
+
+%% keyii will set \keyii in xkvesa.sty
+%% keyiv will be passed to xkvesb.sty as unknown option
+%% the other input will be passed on to xkvesb as well.
+\usepackage[keyii=test2,keyiv=test4,test5]{xkvesa}
+
+%% keyvii will set \keyvii in xkvesc.sty
+\usepackage[keyvii]{xkvesc}
+
+\title{\textsf{xkeyval} package\\\normalsize\emph{Example 2}}
+\author{Hendri Adriaens}
+\setlength{\parindent}{0cm}
+
+\makeatletter
+\let\@tempa\@classoptionslist
+\let\@tempb\@unusedoptionlist
+
+\begin{document}
+\maketitle
+
+This example demonstrates the use of the new macros for declaring
+class and package options of the \textsf{xkeyval} package. Please
+study the files \verb+xkvex2.tex+, \verb+xkveca.cls+,
+\verb+xkvecb.cls+, \verb+xkvesa.sty+, \verb+xkvesb.sty+ and
+\verb+xkvesc.sty+ carefully to understand the output below.\\
+
+Set by \verb+xkveca.cls+: \keyi\par
+Set by \verb+xkvesa.sty+, copied from \verb+\documentclass+: \keyia\par
+Set by \verb+xkvesa.sty+: \keyii\par
+Set by \verb+xkvesb.sty+, passed on from \verb+xkvesa.sty+: \keyiii\par
+Set by \verb+xkvesb.sty+, passed on as unknown key from \verb+xkvesa.sty+: \keyiv\par
+Set by \verb+xkvesb.sty+, passed on as unknown from \verb+xkvesa.sty+: \keyv\par
+Set by the class, copied by \verb+xkvesc.sty+: \keyvi\par
+Set by \verb+xkvesc.sty+: \keyvii\par
+Set by \verb+xkvecb.cls+, passed on from \verb+xkveca.cls+: \keyviii\\
+
+The document class is: \XKV@documentclass\par
+Unused global options: \@tempb\\
+
+Notice the content of the following macros.\par
+\verb+\@classoptionslist+: \@tempa\par
+\verb+\XKV@classoptionslist+: \XKV@classoptionslist\\
+
+This shows that \verb+key=value+ pairs have been deleted from the
+class options list so that subsequent packages which are not using
+\textsf{xkeyval} and are scanning this list will not run into
+problems.\\
+
+\end{document}
+%</xkvex3>
+%
+%<*xkvex4>
+%% Load LaTeX kernel macros patch
+\RequirePackage{xkvltxp}
+
+%% keyi will set \keyi in xkveca.cls
+%% keyvi will set \keyvi in xkveca.cls and xkvesc.sty will pick
+%% it up from \documentclass and redefine it
+%% IgnoredGlobal and another=key will be considered as global
+%% options to be passed on to packages. Not used anymore.
+\documentclass[keyi=test1 on page \thepage,keyvi,another=key,IgnoredGlobal,10pt]{xkveca}
+
+%% keyii will set \keyii in xkvesa.sty
+%% keyiv will be passed to xkvesb.sty as unknown option
+%% the other input will be passed on to xkvesb as well.
+\usepackage[keyii=test2 on page \thepage,keyiv=test4 on page \thepage,test5]{xkvesa}
+
+%% keyvii will set \keyvii in xkvesc.sty
+\usepackage[keyvii]{xkvesc}
+
+\title{\textsf{xkeyval} package\\\normalsize\emph{Example 3}}
+\author{Hendri Adriaens}
+\setlength{\parindent}{0cm}
+
+\makeatletter
+\let\@tempa\@classoptionslist
+\let\@tempb\@unusedoptionlist
+\let\@tempc\XKV@classoptionslist
+\@onelevel@sanitize\@tempc
+
+\begin{document}
+\maketitle
+
+This example demonstrates the use of the new macros for declaring
+class and package options of the \textsf{xkeyval} package. Please
+study the files \verb+xkvex2.tex+, \verb+xkveca.cls+,
+\verb+xkvecb.cls+, \verb+xkvesa.sty+, \verb+xkvesb.sty+ and
+\verb+xkvesc.sty+ carefully to understand the output below.\\
+
+Set by \verb+xkveca.cls+: \keyi\par
+Set by \verb+xkvesa.sty+, copied from \verb+\documentclass+: \keyia\par
+Set by \verb+xkvesa.sty+: \keyii\par
+Set by \verb+xkvesb.sty+, passed on from \verb+xkvesa.sty+: \keyiii\par
+Set by \verb+xkvesb.sty+, passed on as unknown from \verb+xkvesa.sty+: \keyiv\par
+Set by \verb+xkvesb.sty+, passed on as unknown from \verb+xkvesa.sty+: \keyv\par
+Set by the class, copied by \verb+xkvesc.sty+: \keyvi\par
+Set by \verb+xkvesc.sty+: \keyvii\par
+Set by \verb+xkvecb.cls+, passed on from \verb+xkveca.cls+: \keyviii\\
+
+The document class is: \XKV@documentclass\par
+Unused global options: \texttt{\@tempb}\\
+
+Notice the content of the following macros.\par
+\verb+\@classoptionslist+: \texttt{\@tempa}\par
+\verb+\XKV@classoptionslist+:\par\texttt{\@tempc}\\
+
+This shows that \verb+key=value+ pairs have been deleted from the
+class options list so that subsequent packages which are not using
+\textsf{xkeyval} and are scanning this list will not run into
+problems.\\
+
+\newpage
+This page shows that key values are only expanded when they are
+actually used. They are not expanded during option processing.\\
+
+\keyi\par
+\keyii\par
+\keyiv
+
+\end{document}
+%</xkvex4>
+%
+%<*xkveca>
+\ProvidesClass{xkveca}
+\usepackage{xkeyval}
+\let\keyi\@empty
+\let\keyvi\@empty
+\DeclareOptionX{keyi}{\def\keyi{#1}}
+%% this key has a default value
+\DeclareOptionX{keyvi}[{test 6}]{\def\keyvi{#1}}
+%% pass option to class xkvesb.cls
+\PassOptionsToClass{notitlepage}{xkvecb}
+\PassOptionsToClass{keyviii={test 8}}{xkvecb}
+%% pass unknown options to article
+\DeclareOptionX*{\PassOptionsToClass{\CurrentOption}{article}}
+%% process options
+\ProcessOptionsX
+%% load another class
+\LoadClass{xkvecb}
+%</xkveca>
+%
+%<*xkvecb>
+\ProvidesClass{xkvecb}
+%% pass any unknown option to article
+\DeclareOptionX{keyviii}{\def\keyviii{#1}}
+\DeclareOptionX*{\PassOptionsToClass{\CurrentOption}{article}}
+\ProcessOptionsX*
+%% load article
+\LoadClass{article}
+%</xkvecb>
+%
+%<*xkvesa>
+\ProvidesPackage{xkvesa}
+\let\keyia\@empty
+\let\keyii\@empty
+%% keyi has been used in \documentclass
+%% this key uses that information to set another macro
+%% to do this, \ProcessOptionsX* is necessary.
+%% the value from the \documentclass is copied.
+\DeclareOptionX{keyi}{\def\keyia{#1}}
+\DeclareOptionX{keyii}{\def\keyii{#1}}
+%% pass any unknown keys to xkvesb.sty
+\DeclareOptionX*{\PassOptionsToPackage{\CurrentOption}{xkvesb}}
+%% pass a specific key=value to xkvesb.sty
+\PassOptionsToPackage{keyiii={test 3}}{xkvesb}
+%% process options. use the * to pick up options from \documentclass
+\ProcessOptionsX*
+\RequirePackage{xkvesb}
+%</xkvesa>
+%
+%<*xkvesb>
+\ProvidesPackage{xkvesb}
+\let\keyiii\@empty
+\let\keyiv\@empty
+\let\keyv\@empty
+%% use multiple families to define options
+\DeclareOptionX[xkvesb]<famiii>{keyiii}{\def\keyiii{#1}}
+\DeclareOptionX[xkvesb]<famiv>{keyiv}{\def\keyiv{#1}}
+%% define \keyv as \CurrentOption
+\DeclareOptionX*{\let\keyv\CurrentOption}
+%% execute options in multiple families
+\ExecuteOptionsX[xkvesb]<famiii>{keyiii={test 3}}
+%% process options in multiple families
+%% do not set keyiii
+\ProcessOptionsX[xkvesb]<famiii,famiv>[keyiii]
+%</xkvesb>
+%
+%<*xkvesc>
+\ProvidesPackage{xkvesc}
+%% redefine \keyvi when keyvi option is specified in \documentclass
+\DeclareOption{keyvi}{\def\keyvi{test 6a}}
+%% keyvii is a package specific key
+\DeclareOption{keyvii}{\def\keyvii{test 7}}
+%% note that this package uses original LaTeX macros for options.
+%% this is possible since xkeyval filters key=value pairs from
+%% the \documentclass options list.
+\ProcessOptions
+%</xkvesc>
+%
+%<*preamble>
+\usepackage{url}
+\usepackage{xkeyval}
+\usepackage{fourier}
+\usepackage{xcolor}
+\usepackage[multiple]{footmisc}
+\usepackage{pst-char}
+\usepackage{listings}
+\lstnewenvironment{command}{%
+ \lstset{columns=flexible,frame=single,backgroundcolor=\color{blue!20},%
+ xleftmargin=\fboxsep,xrightmargin=\fboxsep,escapeinside=`',gobble=1}}{}
+\lstnewenvironment{example}{%
+ \lstset{basicstyle=\footnotesize\ttfamily,columns=flexible,frame=single,%
+ backgroundcolor=\color{yellow!20},xleftmargin=\fboxsep,%
+ xrightmargin=\fboxsep,gobble=1}}{}
+\def\mktitledecor{%
+ \rput[tl]{90}(-6.5,-23.56){%
+ \psline[linewidth=1pt](0,1.5)(\paperheight,1.5)%
+ \rput[lB](.075\paperheight,.5){\pscharpath[linecolor=blue!50,%
+ fillcolor=yellow!20,fillstyle=solid,linewidth=.5pt]%
+ {\Huge\bfseries\sffamily xkeyval}%
+ }%
+ \rput[rB](.925\paperheight,.5){\pscharpath[linecolor=blue!50,%
+ fillcolor=yellow!20,fillstyle=solid,linewidth=.5pt]%
+ {\Huge\bfseries Documentation}%
+ }%
+ \psline[linewidth=1pt](0,0)(\paperheight,0)%
+ }%
+}
+\makeatletter
+\def\tableofcontents{\@starttoc{toc}}
+\def\changes@#1#2#3{\ch@nges #1\@nil{#2}{#3}}
+\def\ch@nges v#1.#2#3\@nil#4#5{%
+ \ifnum#1#2<20\else % Controls displaying changes; 0 displays all.
+ \protected@edef\@tempa{%
+ \noexpand\glossary{\textbf{v#1.#2#3}\hfill\emph{(#4)}%
+ \levelchar
+ \ifx\saved@macroname\@empty
+ \space\actualchar\generalname
+ \else
+ \expandafter\@gobble\saved@macroname
+ \actualchar\string\verb\quotechar*%
+ \verbatimchar\saved@macroname\verbatimchar
+ \fi
+ :\levelchar #5}}%
+ \@tempa
+ \fi\endgroup\@esphack
+}
+\renewenvironment{theglossary}{%
+ \section*{Version history}%
+ This version history displays recent changes only.\par\bigskip
+ \GlossaryParms \let\item\@idxitem \ignorespaces
+}{}%
+\def\eTeX{$\m@th\varepsilon$-\TeX}
+\def\DescribeMacros{\leavevmode\@bsphack
+ \begingroup\MakePrivateLetters\Describe@Macros}
+\def\Describe@Macros#1{\endgroup\strut
+ \marginpar{\raggedleft
+ \def\@tempa{#1}\count@\z@
+ \XKV@for@o\@tempa\@tempa{%
+ \ifnum\count@>\z@\\\fi\advance\count@\@ne
+ \MacroFont\expandafter\string\@tempa
+ \expandafter\SpecialUsageIndex\expandafter{\@tempa}%
+ }}%
+ \@esphack\ignorespaces
+}
+\def\DescribeOption#1{\leavevmode\@bsphack
+ \marginpar{\raggedleft\PrintDescribeOption{#1}}%
+ \SpecialOptionIndex{#1}\@esphack\ignorespaces}
+\def\PrintDescribeOption#1{\strut\emph{option}\\\MacroFont #1\ }
+\def\SpecialOptionIndex#1{\@bsphack
+ \index{#1\actualchar{\protect\ttfamily#1}
+ (option)\encapchar usage}%
+ \index{options:\levelchar#1\actualchar{\protect\ttfamily#1}\encapchar
+ usage}\@esphack}
+\def\DescribeOptions#1{\leavevmode\@bsphack
+ \marginpar{\raggedleft\strut\emph{options}%
+ \@for\@tempa:=#1\do{%
+ \\\strut\MacroFont\@tempa\SpecialOptionIndex\@tempa
+ }}\@esphack\ignorespaces}
+\makeatother
+\def\PrintChangesX{%
+ \begingroup
+ \let\efill\relax
+ \PrintChanges
+ \endgroup
+}
+\def\PrintIndexX{%
+ \begingroup
+ \setcounter{IndexColumns}{2}
+ \setlength{\columnsep}{18pt}%
+ \setlength{\columnseprule}{.4pt}%
+ \PrintIndex
+ \endgroup
+}
+\def\larg#1{{\ttfamily\char`\<}\meta{#1}{\ttfamily\char`\>}}
+\def\pf#1{\textsf{#1}}
+\EnableCrossrefs
+\RecordChanges
+\CodelineIndex
+%</preamble>
+%
+%<*bib>
+@MISC{LaTeXbase,
+ author = {Johannes Braams and David Carlisle and Alan Jeffrey and Leslie Lamport
+ and Frank Mittelbach and Chris Rowley and Rainer Sch\"opf},
+ title = {The {\LaTeXe} Sources},
+ howpublished = {\url{CTAN:/macros/latex/base}},
+ year = 2003
+}
+
+@BOOK{companion,
+ author = {Frank Mittelbach and Michel Goossens and Johannes Braams and David Carlisle and Chris Rowley},
+ title = {The {\LaTeX} {C}ompanion, {S}econd {E}dition},
+ year = {2004},
+ publisher = {{Addison-Wesley}}
+}
+
+@MISC{keyval,
+ author = {David Carlisle},
+ title = {\pf{keyval} package, v1.13, 1999/03/16},
+ howpublished = {\url{CTAN:/macros/latex/required/graphics}}
+}
+
+@MISC{extract,
+ author = {Hendri Adriaens},
+ title = {\pf{extract} package},
+ howpublished = {\url{CTAN:/macros/latex/contrib/extract}}
+}
+
+@MISC{PSTricks,
+ author = {{Timothy Van} {Zandt et al.}},
+ title = {\pf{PSTricks} package, v1.04, 2004/06/22},
+ howpublished = {\url{CTAN:/graphics/pstricks}}
+}
+
+@MISC{PSTricksWeb,
+ author = {Herbert Vo\ss},
+ title = {\pf{PSTricks} website},
+ howpublished = {\url{http://www.pstricks.de}}
+}
+%</bib>