From 81231e60a62c9f46b647f59881e9165f01e4c9e2 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 27 Jun 2014 00:38:59 +0000 Subject: xkeyval git-svn-id: svn://tug.org/texlive/trunk@34442 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/xkeyval/README | 27 +- Master/texmf-dist/doc/latex/xkeyval/xkeyval.bib | 8 +- Master/texmf-dist/doc/latex/xkeyval/xkeyval.pdf | Bin 490568 -> 492701 bytes Master/texmf-dist/doc/latex/xkeyval/xkvpream.ble | 8 +- Master/texmf-dist/source/latex/xkeyval/xkeyval.dtx | 3744 ++++++++++---------- Master/texmf-dist/tex/generic/xkeyval/keyval.tex | 8 +- Master/texmf-dist/tex/generic/xkeyval/pst-xkey.tex | 8 +- Master/texmf-dist/tex/generic/xkeyval/xkeyval.tex | 238 +- Master/texmf-dist/tex/generic/xkeyval/xkvex1.tex | 8 +- Master/texmf-dist/tex/generic/xkeyval/xkvex2.tex | 8 +- Master/texmf-dist/tex/generic/xkeyval/xkvex3.tex | 8 +- Master/texmf-dist/tex/generic/xkeyval/xkvex4.tex | 8 +- Master/texmf-dist/tex/generic/xkeyval/xkvtxhdr.tex | 8 +- Master/texmf-dist/tex/generic/xkeyval/xkvutils.tex | 271 ++ Master/texmf-dist/tex/latex/xkeyval/pst-xkey.sty | 8 +- Master/texmf-dist/tex/latex/xkeyval/xkeyval.sty | 10 +- Master/texmf-dist/tex/latex/xkeyval/xkveca.cls | 8 +- Master/texmf-dist/tex/latex/xkeyval/xkvecb.cls | 8 +- Master/texmf-dist/tex/latex/xkeyval/xkvesa.sty | 8 +- Master/texmf-dist/tex/latex/xkeyval/xkvesb.sty | 8 +- Master/texmf-dist/tex/latex/xkeyval/xkvesc.sty | 8 +- Master/texmf-dist/tex/latex/xkeyval/xkvltxp.sty | 18 +- Master/texmf-dist/tex/latex/xkeyval/xkvview.sty | 8 +- 23 files changed, 2262 insertions(+), 2174 deletions(-) create mode 100644 Master/texmf-dist/tex/generic/xkeyval/xkvutils.tex (limited to 'Master') diff --git a/Master/texmf-dist/doc/latex/xkeyval/README b/Master/texmf-dist/doc/latex/xkeyval/README index f6bf088d172..24959e0fe04 100644 --- a/Master/texmf-dist/doc/latex/xkeyval/README +++ b/Master/texmf-dist/doc/latex/xkeyval/README @@ -1,5 +1,5 @@ -xkeyval v2.6d -------------- +xkeyval v2.7 +------------ This package is an extension of the keyval package by David Carlisle and offers additional macros for setting keys and declaring and @@ -7,7 +7,7 @@ setting class or package options. This distribution also includes the following additional packages: xkvview v1.4a : viewer utility for package programmers -xkvltxp v1.2 : LaTeX kernel patch to allow expandable macros in +xkvltxp v1.3 : LaTeX kernel patch to allow expandable macros in package options pst-xkey v1.6 : specialization of the xkeyval package for PSTricks packages @@ -22,12 +22,12 @@ First check whether this package can be installed by the distribution that you use, since that will simplify installation. For manual installations, the structure and supposed location in a TDS compliant TeX-tree is shown in the overview below. In words, -keyval.tex, pst-xkey.tex, xkvtxhdr.tex and xkeyval.tex should be -available to TeX and LaTeX; pst-xkey.sty, xkeyval.sty, xkvview.sty -and xkvltxp.sty should be available to LaTeX. The package to which a -specific run file belongs, is denoted in between square brackets. -Don't forget to update your filename database after installing the -files. +keyval.tex, pst-xkey.tex, xkvutils.tex, xkvtxhdr.tex and xkeyval.tex +should be available to TeX and LaTeX; pst-xkey.sty, xkeyval.sty, +xkvview.sty and xkvltxp.sty should be available to LaTeX. The package +to which a specific run file belongs, is denoted in between square +brackets. Don't forget to update your filename database after installing +the files. CTAN:/macros/latex/contrib/xkeyval: official location | @@ -36,6 +36,7 @@ CTAN:/macros/latex/contrib/xkeyval: official location | `- xkeyval.pdf : /doc/latex/xkeyval |- run | |- keyval.tex : /tex/generic/xkeyval [xkeyval] + | |- xkvutils.tex : /tex/generic/xkeyval [xkeyval] | |- pst-xkey.sty : /tex/latex/xkeyval [pst-xkey] | |- pst-xkey.tex : /tex/generic/xkeyval [pst-xkey] | |- xkeyval.sty : /tex/latex/xkeyval [xkeyval] @@ -76,11 +77,11 @@ 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. +xkvltxp.sty, xkvutils.tex, 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. +xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. diff --git a/Master/texmf-dist/doc/latex/xkeyval/xkeyval.bib b/Master/texmf-dist/doc/latex/xkeyval/xkeyval.bib index 0d51b05cb13..224af8e62e6 100644 --- a/Master/texmf-dist/doc/latex/xkeyval/xkeyval.bib +++ b/Master/texmf-dist/doc/latex/xkeyval/xkeyval.bib @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% @MISC{LaTeXbase, author = {Johannes Braams and David Carlisle and Alan Jeffrey and Leslie Lamport diff --git a/Master/texmf-dist/doc/latex/xkeyval/xkeyval.pdf b/Master/texmf-dist/doc/latex/xkeyval/xkeyval.pdf index 502e0a6065d..3ae61104626 100644 Binary files a/Master/texmf-dist/doc/latex/xkeyval/xkeyval.pdf and b/Master/texmf-dist/doc/latex/xkeyval/xkeyval.pdf differ diff --git a/Master/texmf-dist/doc/latex/xkeyval/xkvpream.ble b/Master/texmf-dist/doc/latex/xkeyval/xkvpream.ble index b0f3e915a40..705ea8c3d28 100644 --- a/Master/texmf-dist/doc/latex/xkeyval/xkvpream.ble +++ b/Master/texmf-dist/doc/latex/xkeyval/xkvpream.ble @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \usepackage{url} \usepackage{xkeyval} diff --git a/Master/texmf-dist/source/latex/xkeyval/xkeyval.dtx b/Master/texmf-dist/source/latex/xkeyval/xkeyval.dtx index 07ce2c46f7d..b8bb4ed4e25 100644 --- a/Master/texmf-dist/source/latex/xkeyval/xkeyval.dtx +++ b/Master/texmf-dist/source/latex/xkeyval/xkeyval.dtx @@ -17,6 +17,7 @@ % keyval.tex % xkvtxhdr.tex % pst-xkey.tex +% xkvutils.tex % Additional to these files, LaTeX should be able to locate % the following files: % xkeyval.sty @@ -42,14 +43,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% % \fi % @@ -68,6 +69,7 @@ \file{xkvltxp.sty}{\from{xkeyval.dtx}{xkvltxpatch}} \file{keyval.tex}{\from{xkeyval.dtx}{xkvkeyval}} \file{xkvtxhdr.tex}{\from{xkeyval.dtx}{xkvheader}} + \file{xkvutils.tex}{\from{xkeyval.dtx}{xkvutils}} \file{pst-xkey.tex}{\from{xkeyval.dtx}{pxktex}} \file{pst-xkey.sty}{\from{xkeyval.dtx}{pxklatex}} \file{xkvex1.tex}{\from{xkeyval.dtx}{xkvex1}} @@ -182,10 +184,11 @@ macro. \PrintChangesX\PrintIndexX % \changes{v2.6c}{2014/04/27}{Added support for \cs{par} to support similar % changes in \pf{keyval}} % \changes{v2.6d}{2014/05/09}{Implemented fix conform fix in \pf{keyval}} +% \changes{v2.7}{2014/05/25}{Moved several utility macros to \pf{xkvutils}} % % \GetFileInfo{xkeyval.sty} % -% \CheckSum{3025} +% \CheckSum{3047} % %\DoNotIndex{\:,\@,\@@,\@backslashchar,\@ehc,\@empty,\@expandtwoargs, %\@for,\@forloop,\@fornoop,\@fortmp,\@gobble,\@gobbletwo,\@if,\@ifnch, @@ -2038,13 +2041,12 @@ macro. \PrintChangesX\PrintIndexX \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). +% Load some basic utilities. +% \begin{macrocode} +\input xkvutils +% \end{macrocode} +% Initializations. % \begin{macrocode} -\newtoks\XKV@toks -\newtoks\XKV@tempa@toks \newcount\XKV@depth \newif\ifXKV@st \newif\ifXKV@sg @@ -2058,2374 +2060,2399 @@ macro. \PrintChangesX\PrintIndexX % Load \LaTeX\ primitives if necessary and provide information. % \begin{macrocode} \ifx\ProvidesFile\@undefined - \message{2014/05/09 v2.6d key=value parser (HA)} + \message{2014/05/25 v2.7 key=value parser (HA)} \input xkvtxhdr \else - \ProvidesFile{xkeyval.tex}[2014/05/09 v2.6d key=value parser (HA)] + \ProvidesFile{xkeyval.tex}[2014/05/25 v2.7 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{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} -\long\def\@firstoftwo#1#2{#1} -\long\def\@secondoftwo#1#2{#2} +\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} -% \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{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} -\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 +\def\XKV@ifstar#1{\@ifnextcharacter*{\@firstoftwo{#1}}} +\def\XKV@ifplus#1{\@ifnextcharacter+{\@firstoftwo{#1}}} % \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. +% \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} -\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 +\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 - \expandafter\@secondoftwo + \edef\XKV@prefix{\ifx\XKV@prefix\@empty\else\XKV@prefix @\fi}% \fi - {#2}{#3}#4% } % \end{macrocode} % \end{macro} -% \end{macro} -% \begin{macro}{\XKV@for@n} -% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} -% \changes{v2.6a}{2008/08/13}{Use private scratch register} -% \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{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} -\long\def\XKV@for@n#1#2#3{% - \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% - \ifx#2\@empty - \XKV@for@break - \else - \expandafter\XKV@f@r - \fi - #2{#3}#1,\@nil,% +\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@f@r} -% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} -% \changes{v2.6a}{2008/08/13}{Use private scratch register} -% \meta{cmd}\marg{function}\meta{entry}|,|\\ -% Looping macro. +% \begin{macro}{\XKV@srstate} +% \changes{v2.5f}{2006/11/18}{Added \texttt{XKV@tkey} and \texttt{XKV@rm} to solve bugs} +% \changes{v2.5g}{2006/12/19}{Removed \texttt{XKV@rm} again on user request} +% \changes{v2.6b}{2012/10/14}{Added \texttt{CurrentOption} to fix class options not being +% removed from \cs{@unusedoptionlist} when \cs{setkeys} is nested in \cs{ProcessOptionsX}} +% \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} -\long\def\XKV@f@r#1#2#3,{% - \XKV@tempa@toks{#3}\edef#1{\the\XKV@tempa@toks}% - \ifx#1\@nnil - \expandafter\@gobbletwo - \else - #2\expandafter\XKV@f@r - \fi - #1{#2}% +\def\XKV@srstate#1#2{% + \ifx\@empty#2\@empty\advance\XKV@depth\@ne\fi + \XKV@for@n{XKV@prefix,XKV@fams,XKV@tkey,XKV@na,% + ifXKV@st,ifXKV@pl,ifXKV@knf,CurrentOption}\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@for@break} -% \meta{text}|\@nil,|\\ -% Macro to stop the for-loop. +% \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} -\long\def\XKV@for@break #1\@nil,{\fi} +\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} -% \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{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} -\long\def\XKV@for@en#1#2#3{\XKV@f@r#2{#3}#1,\@nil,} +\def\XKV@testoptb#1{\@testopt{\XKV@t@stoptb#1}{KV}} +\def\XKV@t@stoptb#1[#2]#3{% % \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. +% Set prefix. % \begin{macrocode} -\long\def\XKV@for@eo#1#2#3{% - \def#2{\XKV@f@r#2{#3}}\expandafter#2#1,\@nil,% -} + \XKV@makepf{#2}% % \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. +% Set header. % \begin{macrocode} -\long\def\XKV@whilist#1#2#3\fi#4{% + \XKV@makehd{#3}% % \end{macrocode} -% Check whether the condition is true and start iteration. +% Save family name for later use. % \begin{macrocode} - #3\expandafter\XKV@wh@list#1,\@nil,\@nil\@@#2#3\fi{#4}{}\fi + \KV@@sp@def\XKV@tfam{#3}% + #1% } % \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{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} -% If we find the end of the list, stop. +% \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} - \ifx#3\@nnil - \def#3{#6}\expandafter\XKV@wh@l@st - \else +\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} -% 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. +% |\ifXKV@st| gives the presence of an optional default value. % \begin{macrocode} - #4% - #5\expandafter\expandafter\expandafter\XKV@wh@list + \@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 - \def#3{#6}\expandafter\expandafter\expandafter\XKV@wh@l@st + \expandafter\@firstoftwo \fi - \fi - #2\@@#3#4\fi{#5}{#1}% + }% + \XKV@@ifcmd#1#2{\@nil}\@nil#3% } % \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. +% \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} -\long\def\XKV@wh@l@st#1\@@#2#3\fi#4#5{} +\def\XKV@getkeyname#1#2{\expandafter\XKV@g@tkeyname#1=\@nil#2} % \end{macrocode} % \end{macro} -% \begin{macro}{\XKV@addtomacro@n} -% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} -% \changes{v2.6a}{2008/08/13}{Use private scratch register} -% \meta{macro}\marg{content}\\ -% Adds \meta{content} to \meta{macro} without expanding it. +% \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} -\long\def\XKV@addtomacro@n#1#2{% - \XKV@tempa@toks\expandafter{#1#2}% - \edef#1{\the\XKV@tempa@toks}% +\long\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@addtomacro@o} -% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} -% \changes{v2.6a}{2008/08/13}{Use private scratch register} -% \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{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@addtomacro@o#1#2{% - \expandafter\XKV@addtomacro@n\expandafter#1\expandafter{#2}% +\def\XKV@getsg#1#2{% + \expandafter\XKV@ifcmd\expandafter{#1}\global#2\XKV@sgtrue\XKV@sgfalse } % \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{macro}{\XKV@define@default} +% \marg{key}\marg{default}\\ +% Defines the default value macro for \meta{key} and given |\XKV@header|. % \begin{macrocode} -\def\XKV@addtolist@n#1#2{% - \ifx#1\@empty - \XKV@addtomacro@n#1{#2}% - \else - \XKV@addtomacro@n#1{,#2}% - \fi +\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}{\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{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\XKV@addtolist@o#1#2{% - \ifx#1\@empty - \XKV@addtomacro@o#1#2% - \else - \XKV@addtomacro@o#1{\expandafter,#2}% - \fi -} +\def\define@key{\XKV@testoptb\XKV@define@key} % \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{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@addtolist@x#1#2{\edef#1{#1\ifx#1\@empty\else,\fi#2}} +\def\XKV@define@key#1{% + \@ifnextchar[{\XKV@d@fine@k@y{#1}}{% + \long\expandafter\def\csname\XKV@header#1\endcsname####1% + }% +} % \end{macrocode} % \end{macro} -% \begin{macro}{\@selective@sanitize} -% \begin{macro}{\@s@lective@sanitize} -% \changes{v2.5a}{2005/05/31}{Added missing `\%'} -% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} -% \changes{v2.6a}{2008/08/13}{Use private scratch register} -% \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{macro}{\XKV@d@fine@key} +% \marg{key}\oarg{default}\\ +% Defines the key macro and the default value macro. % \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\XKV@tempa@toks\expandafter{#3}% - \expandafter\endgroup\expandafter\toks@\expandafter{\the\XKV@tempa@toks}% - \edef#3{\the\toks@}% +\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}{\@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{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\@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 +\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}{\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{macro}{\define@cmdkeys} +% \oarg{prefix}\marg{family}\oarg{mp}\marg{keys}\\ +% Define multiple command keys. % \begin{macrocode} -\long\def\XKV@checksanitizea#1#2{% - \XKV@ch@cksanitize{#1}#2=% - \ifin@\else\XKV@ch@cksanitize{#1}#2,\fi - \ifin@\@selective@sanitize[0]{,=}#2\fi -} +\def\define@cmdkeys{\XKV@testoptd\XKV@define@cmdkeys{cmd}} % \end{macrocode} % \end{macro} -% \begin{macro}{\XKV@checksanitizeb} -% \marg{content}\meta{cmd}\\ -% Similar to |\XKV@checksanitizea|, but only checks commas. +% \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@checksanitizeb#1#2{% - \XKV@ch@cksanitize{#1}#2,% - \ifin@\@selective@sanitize[0],#2\fi +\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}{\XKV@ch@cksanitize} -% \changes{v1.8b}{2004/12/22}{Fixed bug for key value \cs{@empty}} -% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} -% \changes{v2.6a}{2008/08/13}{Use private scratch register} -% \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{macro}{\define@choicekey} +% |*+|\oarg{prefix}\marg{family}\\ +% Choice keys. First check optional star, plus and prefix and store the +% family. % \begin{macrocode} -\long\def\XKV@ch@cksanitize#1#2#3{% - \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% - \@onelevel@sanitize#2% +\def\define@choicekey{\XKV@testopta{\XKV@testoptb\XKV@define@choicekey}} % \end{macrocode} -% Check whether there is at least one |=| present. +% \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} - \@expandtwoargs\in@#3{#2}% - \ifin@ +\def\XKV@define@choicekey#1{\@testopt{\XKV@d@fine@choicekey{#1}}{}} % \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). +% \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} - \long\def#2##1#3##2\@nil{% - \XKV@tempa@toks{##2}\edef#2{\the\XKV@tempa@toks}% - \ifx#2\@empty\else\in@false\fi - }% - #2#1#3\@nil - \fi - \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% +\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@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{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@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 +\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@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{macro}{\XKV@d@fine@ch@ic@key} +% \marg{key}\\ +% Eat correct number of arguments. % \begin{macrocode} -\def\XKV@merge#1#2#3{% - \XKV@checksanitizea{#2}\XKV@tempa +\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} -% Start the loop over the new presets. At every iteration, one new preset -% will be compared with old presets. +% \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} - \XKV@for@o\XKV@tempa\XKV@tempa{% - \XKV@pltrue +\def\XKV@d@f@ne@ch@ic@key#1#2{\XKV@d@f@n@@ch@ic@k@y#1{{#2}}} % \end{macrocode} -% Retrieve the key name of the new item at hand. +% \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} - #3\XKV@tempa\XKV@tempb +\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} -% Store the (partially updated) old list in a temp macro and empty -% the original macro. +% \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} - \let\XKV@tempc#1% - \let#1\@empty +\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} -% Start a loop over the old list. +% \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} - \XKV@for@o\XKV@tempc\XKV@tempc{% +\def\define@boolkey{\XKV@t@stopta{\XKV@testoptd\XKV@define@boolkey{}}} % \end{macrocode} -% Retrieve the key name of the old key at hand. +% \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} - #3\XKV@tempc\XKV@tempd - \ifx\XKV@tempb\XKV@tempd +\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} -% 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. +% \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} - \XKV@plfalse - \XKV@addtolist@o#1\XKV@tempa - \else +\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} -% If the key names are not equal, then just append the current item -% to the list. +% \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} - \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 +\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@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{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} - \XKV@for@o\XKV@tempb\XKV@tempb{% +\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} -% Get the key name to identify the current entry. +% \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} - #3\XKV@tempb\XKV@tempc +\def\define@boolkeys{\XKV@plfalse\XKV@testoptd\XKV@define@boolkeys{}} % \end{macrocode} -% If the current key name is in the list, do not add it anymore. +% \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} - \@expandtwoargs\in@{,\XKV@tempc,}{,\XKV@tempa,}% - \ifin@\else\XKV@addtolist@o#1\XKV@tempb\fi +\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} -% 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{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@warn#1{\message{xkeyval warning: #1}} -\def\XKV@err#1{\errmessage{xkeyval error: #1}} -\def\KV@errx{\XKV@err} -\let\KV@err\KV@errx +\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} -% \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{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@ifstar#1{\@ifnextcharacter*{\@firstoftwo{#1}}} -\def\XKV@ifplus#1{\@ifnextcharacter+{\@firstoftwo{#1}}} +\def\XKV@cc{\XKV@testopta{\@testopt\XKV@checkchoice{}}} % \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{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@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 +\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 - \edef\XKV@prefix{\ifx\XKV@prefix\@empty\else\XKV@prefix @\fi}% + \def\XKV@tempa{\XKV@ch@ckchoice#1\@nil{#2}{#3}}% \fi + \ifXKV@st}\fi\XKV@tempa } % \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{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@makehd#1{% - \expandafter\KV@@sp@def\expandafter\XKV@header\expandafter{#1}% - \edef\XKV@header{% - \XKV@prefix\ifx\XKV@header\@empty\else\XKV@header @\fi - }% +\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@srstate} -% \changes{v2.5f}{2006/11/18}{Added \texttt{XKV@tkey} and \texttt{XKV@rm} to solve bugs} -% \changes{v2.5g}{2006/12/19}{Removed \texttt{XKV@rm} again on user request} -% \changes{v2.6b}{2012/10/14}{Added \texttt{CurrentOption} to fix class options not being -% removed from \cs{@unusedoptionlist} when \cs{setkeys} is nested in \cs{ProcessOptionsX}} -% \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{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@srstate#1#2{% - \ifx\@empty#2\@empty\advance\XKV@depth\@ne\fi - \XKV@for@n{XKV@prefix,XKV@fams,XKV@tkey,XKV@na,% - ifXKV@st,ifXKV@pl,ifXKV@knf,CurrentOption}\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 -} +\def\XKV@ch@ckch@ice#1#2#3{% + \def\XKV@tempa{#1}% % \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. +% If we have a \meta{bin}, store the input there. % \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}} + \ifx\XKV@tempa\@nnil\let\XKV@tempa\@empty\else + \def\XKV@tempa{\def#1{#2}}% + \fi + \in@{,#2,}{,#3,}% + \ifin@ % \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}. +% The \meta{input} is allowed. % \begin{macrocode} -\def\XKV@testoptb#1{\@testopt{\XKV@t@stoptb#1}{KV}} -\def\XKV@t@stoptb#1[#2]#3{% + \ifXKV@pl % \end{macrocode} -% Set prefix. +% If we have a |+|, there are two functions. Execute the first. % \begin{macrocode} - \XKV@makepf{#2}% + \XKV@addtomacro@n\XKV@tempa\@firstoftwo + \else % \end{macrocode} -% Set header. +% Else, we have one function; execute it. % \begin{macrocode} - \XKV@makehd{#3}% + \XKV@addtomacro@n\XKV@tempa\@firstofone + \fi + \else % \end{macrocode} -% Save family name for later use. +% If we have a |+|, there are two functions. Execute the second. % \begin{macrocode} - \KV@@sp@def\XKV@tfam{#3}% - #1% + \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} -% \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{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@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{}% -} +\def\XKV@@ch@ckchoice#1#2#3#4{% % \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. +% 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} -\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{% + \edef\XKV@tempa{\the\count@}\count@\z@ % \end{macrocode} -% |\ifXKV@st| gives the presence of an optional default value. +% The input. % \begin{macrocode} - \@ifnextchar[{\XKV@sttrue#1{#2}{#3}}{\XKV@stfalse#1{#2}{#3}[]}% -} + \def\XKV@tempb{#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. +% Define the while loop. % \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 + \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 - \expandafter\@firstoftwo - \fi - }% - \XKV@@ifcmd#1#2{\@nil}\@nil#3% -} + \ifx#1\XKV@tempb % \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}. +% We found \meta{input} in \meta{allowed}. +% Save the number of the \meta{input} in the list \meta{allowed}. % \begin{macrocode} -\def\XKV@getkeyname#1#2{\expandafter\XKV@g@tkeyname#1=\@nil#2} + \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} -% \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}. +% Increase counter and check next item in the list \meta{allowed}. % \begin{macrocode} -\long\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}% + \advance\count@\@ne + \let\XKV@tempd\XKV@tempc + \fi + \fi + \XKV@tempd }% -} % \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} +% Start the while loop. % \begin{macrocode} -\def\XKV@getsg#1#2{% - \expandafter\XKV@ifcmd\expandafter{#1}\global#2\XKV@sgtrue\XKV@sgfalse + \XKV@tempc#4,\@nil,% } % \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{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@define@default#1#2{% - \expandafter\def\csname\XKV@header#1@default\expandafter - \endcsname\expandafter{\csname\XKV@header#1\endcsname{#2}}% -} +\def\XKV@@ch@ckch@ice#1\@nil,{\@firstoftwo} +\def\XKV@@ch@ckch@ic@#1\@nil,{\@firstofone} % \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{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\XKV@define@key#1{% - \@ifnextchar[{\XKV@d@fine@k@y{#1}}{% - \long\expandafter\def\csname\XKV@header#1\endcsname####1% - }% -} +\def\key@ifundefined{\@testopt\XKV@key@ifundefined{KV}} % \end{macrocode} % \end{macro} -% \begin{macro}{\XKV@d@fine@key} -% \marg{key}\oarg{default}\\ -% Defines the key macro and the default value 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@d@fine@k@y#1[#2]{% - \XKV@define@default{#1}{#2}% - \expandafter\def\csname\XKV@header#1\endcsname##1% +\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}{\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{macro}{\XKV@key@if@ndefined} +% \marg{key}\\ +% Loop over the list of families until we find the key in a family. % \begin{macrocode} -\def\define@cmdkey{\XKV@testoptd\XKV@define@cmdkey{cmd}} +\def\XKV@key@if@ndefined#1{% + \XKV@knftrue + \KV@@sp@def\XKV@tkey{#1}% % \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}. +% Loop over possible families. % \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}% -} + \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{% % \end{macrocode} -% \end{macro} -% \begin{macro}{\define@cmdkeys} -% \oarg{prefix}\marg{family}\oarg{mp}\marg{keys}\\ -% Define multiple command keys. +% Set the header. % \begin{macrocode} -\def\define@cmdkeys{\XKV@testoptd\XKV@define@cmdkeys{cmd}} + \XKV@makehd\XKV@tfam % \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. +% Check whether the macro for the key is defined. % \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]{}% + \XKV@ifundefined{\XKV@header\XKV@tkey}{}{\XKV@knffalse}% }% -} % \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. +% Execute one of the final two arguments depending on state of |\XKV@knf|. % \begin{macrocode} -\def\define@choicekey{\XKV@testopta{\XKV@testoptb\XKV@define@choicekey}} + \ifXKV@knf + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi +} % \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{macro}{\disable@keys} +% \oarg{prefix}\marg{family}\\ +% Macro that make a key produce a warning on use. % \begin{macrocode} -\def\XKV@define@choicekey#1{\@testopt{\XKV@d@fine@choicekey{#1}}{}} +\def\disable@keys{\XKV@testoptb\XKV@disable@keys} % \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{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@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}}% +\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}{\XKV@d@fine@ch@icekey} -% \marg{key}\oarg{default}\\ -% Define the default value macro if a default value was specified. +% \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\XKV@d@fine@ch@icekey#1[#2]{% - \XKV@define@default{#1}{#2}% - \XKV@d@fine@ch@ic@key{#1}% -} +\def\presetkeys{\XKV@stfalse\XKV@testoptb\XKV@presetkeys} +\def\gpresetkeys{\XKV@sttrue\XKV@testoptb\XKV@presetkeys} % \end{macrocode} % \end{macro} -% \begin{macro}{\XKV@d@fine@ch@ic@key} -% \marg{key}\\ -% Eat correct number of arguments. +% \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@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 +\def\XKV@presetkeys#1#2{% + \XKV@pr@setkeys{#1}{preseth}% + \XKV@pr@setkeys{#2}{presett}% } % \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{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@d@f@ne@ch@ic@key#1#2{\XKV@d@f@n@@ch@ic@k@y#1{{#2}}} +\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}{\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{macro}{\delpresetkeys} +% \begin{macro}{\gdelpresetkeys} +% \oarg{prefix}\marg{family}\\ +% Macros to remove entries from presets. % \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}}} +\def\delpresetkeys{\XKV@stfalse\XKV@testoptb\XKV@delpresetkeys} +\def\gdelpresetkeys{\XKV@sttrue\XKV@testoptb\XKV@delpresetkeys} % \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. +% \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@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}% +\def\XKV@delpresetkeys#1#2{% + \XKV@d@lpresetkeys{#1}{preseth}% + \XKV@d@lpresetkeys{#2}{presett}% } % \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{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\define@boolkey{\XKV@t@stopta{\XKV@testoptd\XKV@define@boolkey{}}} +\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}{\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{macro}{\unpresetkeys} +% \begin{macro}{\gunpresetkeys} +% \oarg{prefix}\marg{family}\\ +% Removes presets for a particular family. % \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}% -} +\def\unpresetkeys{\XKV@stfalse\XKV@testoptb\XKV@unpresetkeys} +\def\gunpresetkeys{\XKV@sttrue\XKV@testoptb\XKV@unpresetkeys} % \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'. +% \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@d@fine@boolkey#1#2#3#4#5{% - \XKV@d@f@ne@b@olkey#1{#2}{#3}{#4}% - {{\csname#3\XKV@resa\endcsname#5}}% +\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}{\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{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\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}}% -} +\def\savekeys{\XKV@stfalse\XKV@testoptb\XKV@savekeys} +\def\gsavekeys{\XKV@sttrue\XKV@testoptb\XKV@savekeys} % \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. +% \end{macro} +% \begin{macro}{\XKV@savekeys} +% \marg{key list}\\ +% Check whether something has been saved before. If not, start merging. % \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 +\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}{\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{macro}{\delsavekeys} +% \begin{macro}{\gdelsavekeys} +% \oarg{prefix}\marg{family}\\ +% Remove entries from the list of save keys. % \begin{macrocode} -\def\define@boolkeys{\XKV@plfalse\XKV@testoptd\XKV@define@boolkeys{}} +\def\delsavekeys{\XKV@stfalse\XKV@testoptb\XKV@delsavekeys} +\def\gdelsavekeys{\XKV@sttrue\XKV@testoptb\XKV@delsavekeys} % \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. +% \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@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}% +\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}{\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{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\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}}% -} +\def\unsavekeys{\XKV@stfalse\XKV@testoptb\XKV@unsavekeys} +\def\gunsavekeys{\XKV@sttrue\XKV@testoptb\XKV@unsavekeys} % \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{macro}{\XKV@unsavekeys} +% Workhorse for |\unsavekeys|. % \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 +\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}{\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{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\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 -} +\def\setkeys{\XKV@testopta{\XKV@testoptc\XKV@setkeys}} % \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{macro}{\XKV@setkeys} +% \oarg{na}\marg{key=value list}\\ +% \changes{v1.8a}{2004/12/20}{Solved small bug} +% \changes{v2.5f}{2006/11/18}{Added reset of \cs{CurrentOption}} +% \changes{v2.5g}{2006/12/19}{Avoid reset of \cs{XKV@rm} in nested \cs{setkeys} commands} +% Workhorse for |\setkeys|. % \begin{macrocode} - \ifXKV@pl +\long\def\XKV@setkeys[#1]#2{% + \XKV@checksanitizea{#2}\XKV@resb + \let\XKV@naa\@empty % \end{macrocode} -% If we have a |+|, there are two functions. Execute the first. +% Retrieve a list of key names from the user input. % \begin{macrocode} - \XKV@addtomacro@n\XKV@tempa\@firstoftwo - \else + \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} -% Else, we have one function; execute it. +% Initialize the remaining keys, but only for the outermost level of +% |\setkeys|. % \begin{macrocode} - \XKV@addtomacro@n\XKV@tempa\@firstofone - \fi - \else + \ifnum\XKV@depth=\z@\let\XKV@rm\@empty\fi % \end{macrocode} -% If we have a |+|, there are two functions. Execute the second. +% Now scan the list of families for preset keys and set user input keys. % \begin{macrocode} - \ifXKV@pl - \XKV@addtomacro@n\XKV@tempa\@secondoftwo - \else + \XKV@usepresetkeys{#1}{preseth}% + \expandafter\XKV@s@tkeys\expandafter{\XKV@resb}{#1}% + \XKV@usepresetkeys{#1}{presett}% + \let\CurrentOption\@empty +} % \end{macrocode} -% Else, raise an error and gobble the one function. +% \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} - \XKV@toks{#2}% - \XKV@err{value `\the\XKV@toks' is not allowed}% - \XKV@addtomacro@n\XKV@tempa\@gobble - \fi - \fi - \XKV@tempa +\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@@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{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@@ch@ckchoice#1#2#3#4{% +\long\def\XKV@s@tkeys#1#2{% % \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). +% Define the list of key names which should be ignored. % \begin{macrocode} - \edef\XKV@tempa{\the\count@}\count@\z@ + \XKV@sp@deflist\XKV@na{#2}% % \end{macrocode} -% The input. +% Loop over the key=value list. % \begin{macrocode} - \def\XKV@tempb{#3}% + \XKV@for@n{#1}\CurrentOption{% % \end{macrocode} -% Define the while loop. +% Split key and value. % \begin{macrocode} - \def\XKV@tempc##1,{% - \def#1{##1}% - \ifx#1\@nnil + \expandafter\XKV@s@tk@ys\CurrentOption==\@nil + }% +} % \end{macrocode} -% The \meta{input} was not in \meta{allowed}. Set the number to |-1|. +% \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.} +% \changes{v2.5g}{2006/12/19}{Removed \cs{global} again for consistent +% approach of \cs{XKV@rm} and to allow groups to keep \cs{XKV@rm} local} +% \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#1{#3}\def#2{-1}\count@\XKV@tempa - \ifXKV@pl +\long\def\XKV@s@tk@ys#1=#2=#3\@nil{% % \end{macrocode} -% Execute the macro for the case that input was not allowed. +% Check for |\savevalue| and |\gsavevalue| and remove spaces from around the key name. % \begin{macrocode} - \let\XKV@tempd\@secondoftwo - \else + \XKV@g@tkeyname#1=\@nil\XKV@tkey + \expandafter\KV@@sp@def\expandafter\XKV@tkey\expandafter{\XKV@tkey}% % \end{macrocode} -% If that function does not exist, raise a generic error and gobble -% the function to be executed on good input. +% If the key is empty and a value has been specified, generate an error. % \begin{macrocode} - \XKV@toks{#3}% - \XKV@err{value `\the\XKV@toks' is not allowed}% - \let\XKV@tempd\@gobble - \fi - \else - \ifx#1\XKV@tempb + \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} -% We found \meta{input} in \meta{allowed}. -% Save the number of the \meta{input} in the list \meta{allowed}. +% If in the |\XKV@na| list, ignore the key. % \begin{macrocode} - \edef#2{\the\count@}\count@\XKV@tempa + \@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 - \let\XKV@tempd\XKV@@ch@ckch@ice +% \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 - \let\XKV@tempd\XKV@@ch@ckch@ic@ - \fi - \else % \end{macrocode} -% Increase counter and check next item in the list \meta{allowed}. +% Else, scan the families on the list but stop when the key is found +% or when the list has run out. % \begin{macrocode} - \advance\count@\@ne - \let\XKV@tempd\XKV@tempc + \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{% + \XKV@makehd\XKV@tfam + \XKV@s@tk@ys@{#3}% + }% + \fi \fi - \fi - \XKV@tempd - }% + \ifXKV@knf + \ifXKV@inpox % \end{macrocode} -% Start the while loop. +% We are in the options section. Try to use the macro defined by +% |\DeclareOptionX*|. % \begin{macrocode} - \XKV@tempc#4,\@nil,% -} + \ifx\XKV@doxs\relax % \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. +% For classes, ignore unknown (possibly global) options. For packages, +% raise the standard \LaTeX\ error. % \begin{macrocode} -\def\XKV@@ch@ckch@ice#1\@nil,{\@firstoftwo} -\def\XKV@@ch@ckch@ic@#1\@nil,{\@firstofone} + \ifx\@currext\@clsextension\else + \let\CurrentOption\XKV@tkey\@unknownoptionerror + \fi % \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. +% Pass the option through |\DeclareOptionX*|. % \begin{macrocode} -\def\key@ifundefined{\@testopt\XKV@key@ifundefined{KV}} + \else\XKV@doxs\fi + \else % \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. +% 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} -\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 -} + \ifXKV@st + \XKV@addtolist@o\XKV@rm\CurrentOption + \else + \XKV@err{`\XKV@tkey' undefined in families `\XKV@fams'}% + \fi + \fi + \else % \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. +% 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} -\def\XKV@key@if@ndefined#1{% - \XKV@knftrue - \KV@@sp@def\XKV@tkey{#1}% + \ifXKV@inpox\ifx\XKV@testclass\XKV@documentclass + \expandafter\XKV@useoption\expandafter{\CurrentOption}% + \fi\fi + \fi + \fi + \fi +} % \end{macrocode} -% Loop over possible families. +% \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} - \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{% +\def\XKV@s@tk@ys@#1{% % \end{macrocode} -% Set the header. +% Check whether the key macro exists. % \begin{macrocode} - \XKV@makehd\XKV@tfam + \XKV@ifundefined{\XKV@header\XKV@tkey}{}{% + \XKV@knffalse % \end{macrocode} -% Check whether the macro for the key is defined. +% Check global setting by |\savekeys| to know whether or not to save +% the value of the key at hand. % \begin{macrocode} - \XKV@ifundefined{\XKV@header\XKV@tkey}{}{\XKV@knffalse}% - }% + \XKV@ifundefined{XKV@\XKV@header save}{}{% + \expandafter\XKV@testsavekey\csname XKV@\XKV@header + save\endcsname\XKV@tkey + }% % \end{macrocode} -% Execute one of the final two arguments depending on state of |\XKV@knf|. +% Save the value of a key. % \begin{macrocode} - \ifXKV@knf - \expandafter\@firstoftwo - \else - \expandafter\@secondoftwo - \fi -} + \ifXKV@rkv + \ifXKV@sg\expandafter\global\fi\expandafter\let + \csname XKV@\XKV@header\XKV@tkey @value\endcsname\XKV@tempa + \fi % \end{macrocode} -% \end{macro} -% \begin{macro}{\disable@keys} -% \oarg{prefix}\marg{family}\\ -% Macro that make a key produce a warning on use. +% Replace pointers by saved values. % \begin{macrocode} -\def\disable@keys{\XKV@testoptb\XKV@disable@keys} + \expandafter\XKV@replacepointers\expandafter{\XKV@tempa}% % \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. +% If no value was present, use the default value macro, if one exists. +% Otherwise, issue an error. % \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}}% + \ifx\@empty#1\@empty\XKV@afterelsefi + \XKV@ifundefined{\XKV@header\XKV@tkey @default}{% + \XKV@err{no value specified for key `\XKV@tkey'}% }{% - \edef\XKV@tempc{\noexpand\XKV@define@key{\XKV@tempa}[]}% + \expandafter\expandafter\expandafter\XKV@default + \csname\XKV@header\XKV@tkey @default\endcsname\@nil }% - \expandafter\XKV@tempc\expandafter{\XKV@tempb}% - }% - }% -} + \else\XKV@afterfi % \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. +% Save state in case the key executes |\setkeys| or |\XKV@cc|. % \begin{macrocode} -\def\presetkeys{\XKV@stfalse\XKV@testoptb\XKV@presetkeys} -\def\gpresetkeys{\XKV@sttrue\XKV@testoptb\XKV@presetkeys} + \XKV@srstate{@\romannumeral\XKV@depth}{}% % \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. +% Execute the key. % \begin{macrocode} -\def\XKV@presetkeys#1#2{% - \XKV@pr@setkeys{#1}{preseth}% - \XKV@pr@setkeys{#2}{presett}% -} + \csname\XKV@header\XKV@tkey\expandafter + \endcsname\expandafter{\XKV@tempa}\relax % \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. +% Restore the current state. % \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 + \XKV@srstate{}{@\romannumeral\XKV@depth}% + \fi }% } % \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{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@delpresetkeys#1#2{% - \XKV@d@lpresetkeys{#1}{preseth}% - \XKV@d@lpresetkeys{#2}{presett}% +\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@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{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@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 - }% +\long\def\XKV@replacepointers#1{% + \let\XKV@tempa\@empty + \let\XKV@resa\@empty + \XKV@r@placepointers#1\usevalue\@nil +} +\long\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\@empty + }{% + \@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 + \expandafter\expandafter\expandafter\@empty + \csname XKV@\XKV@header#2@value\endcsname + \fi + }% + \fi } -% \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{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@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 - }% -} +\def\XKV@default#1#2\@nil{% % \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. +% Retrieve the first token in the macro. % \begin{macrocode} -\def\savekeys{\XKV@stfalse\XKV@testoptb\XKV@savekeys} -\def\gsavekeys{\XKV@sttrue\XKV@testoptb\XKV@savekeys} + \expandafter\edef\expandafter\XKV@tempa + \expandafter{\expandafter\@gobble\string#1}% % \end{macrocode} -% \end{macro} -% \end{macro} -% \begin{macro}{\XKV@savekeys} -% \marg{key list}\\ -% Check whether something has been saved before. If not, start merging. +% Construct the name that we expect on the basis of the \pf{keyval} +% and \pf{xkeyval} syntax of default values. % \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 - }% -} + \edef\XKV@tempb{\XKV@header\XKV@tkey}% % \end{macrocode} -% \end{macro} -% \begin{macro}{\delsavekeys} -% \begin{macro}{\gdelsavekeys} -% \oarg{prefix}\marg{family}\\ -% Remove entries from the list of save keys. +% Sanitize |\XKV@tempb| to reset catcodes for comparison with |\XKV@tempa|. % \begin{macrocode} -\def\delsavekeys{\XKV@stfalse\XKV@testoptb\XKV@delsavekeys} -\def\gdelsavekeys{\XKV@sttrue\XKV@testoptb\XKV@delsavekeys} + \@onelevel@sanitize\XKV@tempb + \ifx\XKV@tempa\XKV@tempb % \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. +% 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} -\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 - }% -} + \begingroup + \expandafter\def\csname\XKV@header\XKV@tkey\endcsname##1{% + \gdef\XKV@tempa{##1}% + }% + \csname\XKV@header\XKV@tkey @default\endcsname + \endgroup % \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. +% 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} -\def\unsavekeys{\XKV@stfalse\XKV@testoptb\XKV@unsavekeys} -\def\gunsavekeys{\XKV@sttrue\XKV@testoptb\XKV@unsavekeys} + \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} -% \end{macro} -% \end{macro} -% \begin{macro}{\XKV@unsavekeys} -% Workhorse for |\unsavekeys|. +% Replace the pointers. % \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 - }% -} + \expandafter\XKV@replacepointers\expandafter + {\XKV@tempa}\XKV@afterelsefi % \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. +% Save internal state. % \begin{macrocode} -\def\setkeys{\XKV@testopta{\XKV@testoptc\XKV@setkeys}} + \XKV@srstate{@\romannumeral\XKV@depth}{}% % \end{macrocode} -% \end{macro} -% \begin{macro}{\XKV@setkeys} -% \oarg{na}\marg{key=value list}\\ -% \changes{v1.8a}{2004/12/20}{Solved small bug} -% \changes{v2.5f}{2006/11/18}{Added reset of \cs{CurrentOption}} -% \changes{v2.5g}{2006/12/19}{Avoid reset of \cs{XKV@rm} in nested \cs{setkeys} commands} -% Workhorse for |\setkeys|. +% Execute the key with the (possibly changed) default value. % \begin{macrocode} -\long\def\XKV@setkeys[#1]#2{% - \XKV@checksanitizea{#2}\XKV@resb - \let\XKV@naa\@empty + \expandafter#1\expandafter{\XKV@tempa}\relax % \end{macrocode} -% Retrieve a list of key names from the user input. +% Restore internal state. % \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 - }% + \XKV@srstate{}{@\romannumeral\XKV@depth}% + \else\XKV@afterfi % \end{macrocode} -% Initialize the remaining keys, but only for the outermost level of -% |\setkeys|. +% Save internal state. % \begin{macrocode} - \ifnum\XKV@depth=\z@\let\XKV@rm\@empty\fi + \XKV@srstate{@\romannumeral\XKV@depth}{}% % \end{macrocode} -% Now scan the list of families for preset keys and set user input keys. +% Execute the key with the default value. % \begin{macrocode} - \XKV@usepresetkeys{#1}{preseth}% - \expandafter\XKV@s@tkeys\expandafter{\XKV@resb}{#1}% - \XKV@usepresetkeys{#1}{presett}% - \let\CurrentOption\@empty + \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}{\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{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\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 -} +\def\setrmkeys{\XKV@testopta{\XKV@testoptc\XKV@setrmkeys}} % \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{macro}{\XKV@setrmkeys} +% \oarg{na}\\ +% Submits the keys in |\XKV@rm| to |\XKV@setkeys|. % \begin{macrocode} -\long\def\XKV@s@tkeys#1#2{% +\def\XKV@setrmkeys[#1]{% + \def\XKV@tempa{\XKV@setkeys[#1]}% + \expandafter\XKV@tempa\expandafter{\XKV@rm}% +} % \end{macrocode} -% Define the list of key names which should be ignored. +% \end{macro} +% Reset catcodes. % \begin{macrocode} - \XKV@sp@deflist\XKV@na{#2}% +\XKVcatcodes +% % \end{macrocode} -% Loop over the key=value list. +% \subsection{\texttt{xkeyval.sty}} +% \changes{v1.5}{2004/09/27}{Made macros avoid expansions of options} +% Initialize the package. % \begin{macrocode} - \XKV@for@n{#1}\CurrentOption{% +%<*xkvlatex> +\NeedsTeXFormat{LaTeX2e}[1995/12/01] +\ProvidesPackage{xkeyval} + [2014/05/25 v2.7 package option processing (HA)] % \end{macrocode} -% Split key and value. +% Initializations. Load |xkeyval.tex|, adjust some catcodes to define +% internal macros and initialize the |\DeclareOptionX*| working macro. % \begin{macrocode} - \expandafter\XKV@s@tk@ys\CurrentOption==\@nil - }% +\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} -% \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.} -% \changes{v2.5g}{2006/12/19}{Removed \cs{global} again for consistent -% approach of \cs{XKV@rm} and to allow groups to keep \cs{XKV@rm} local} -% \meta{key}|=|\meta{value}|=#3\@nil|\\ -% Split key name and value (if present). If |#3| non-empty, there was -% no |=|\meta{value}. +% \begin{macro}{\XKV@warn} +% \begin{macro}{\XKV@err} +% Warning and error macros. % \begin{macrocode} -\long\def\XKV@s@tk@ys#1=#2=#3\@nil{% +\def\XKV@warn#1{\PackageWarning{xkeyval}{#1}} +\def\XKV@err#1{\PackageError{xkeyval}{#1}\@ehc} % \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. +% \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} - \ifx\XKV@tkey\@empty - \XKV@toks{#2}% - \ifcat$\the\XKV@toks$\else - \XKV@err{no key specified for value `\the\XKV@toks'}% - \fi - \else +\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 in the |\XKV@na| list, ignore the key. +% If we didn't find the document class, raise an error, otherwise +% filter global options. % \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 +\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} -% If a command with a |+| is used, set keys in all families on the -% list. +% \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} - \XKV@for@eo\XKV@fams\XKV@tfam{% - \XKV@makehd\XKV@tfam - \XKV@s@tk@ys@{#3}% - }% - \else + \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} -% Else, scan the families on the list but stop when the key is found -% or when the list has run out. +% \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} - \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{% - \XKV@makehd\XKV@tfam - \XKV@s@tk@ys@{#3}% - }% - \fi - \fi - \ifXKV@knf - \ifXKV@inpox +\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} -% We are in the options section. Try to use the macro defined by -% |\DeclareOptionX*|. +% \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} - \ifx\XKV@doxs\relax +\def\DeclareOptionX{% + \let\@fileswith@pti@ns\@badrequireerror + \XKV@ifstar\XKV@dox\XKV@d@x +} % \end{macrocode} -% For classes, ignore unknown (possibly global) options. For packages, -% raise the standard \LaTeX\ error. +% \end{macro} +% \begin{macro}{\XKV@dox} +% This macro defines |\XKV@doxs| to be used for unknown options. % \begin{macrocode} - \ifx\@currext\@clsextension\else - \let\CurrentOption\XKV@tkey\@unknownoptionerror - \fi +\long\def\XKV@dox#1{\XKV@toks{#1}\edef\XKV@doxs{\the\XKV@toks}} % \end{macrocode} -% Pass the option through |\DeclareOptionX*|. +% \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} - \else\XKV@doxs\fi - \else +\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} -% If not in the options section, raise an error or add the key to the -% list in |\XKV@rm| when |\setkeys*| has been used. +% \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} - \ifXKV@st - \XKV@addtolist@o\XKV@rm\CurrentOption - \else - \XKV@err{`\XKV@tkey' undefined in families `\XKV@fams'}% - \fi - \fi - \else +\def\ExecuteOptionsX{\XKV@stfalse\XKV@plfalse\XKV@t@stopte\XKV@setkeys} % \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*|. +% \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} - \ifXKV@inpox\ifx\XKV@testclass\XKV@documentclass - \expandafter\XKV@useoption\expandafter{\CurrentOption}% - \fi\fi - \fi - \fi - \fi -} +\def\ProcessOptionsX{\XKV@plfalse\XKV@testopte\XKV@pox} % \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{macro}{\XKV@pox} +% \oarg{na}\\ +% Workhorse for |\ProcessOptionsX| and |\ProcessOptionsX*|. % \begin{macrocode} -\def\XKV@s@tk@ys@#1{% +\def\XKV@pox[#1]{% + \let\XKV@tempa\@empty % \end{macrocode} -% Check whether the key macro exists. +% Set |\XKV@inpox|: indicates that we are in |\ProcessOptionsX| to +% invoke a special routine in |\XKV@s@tkeys|. % \begin{macrocode} - \XKV@ifundefined{\XKV@header\XKV@tkey}{}{% - \XKV@knffalse + \XKV@inpoxtrue % \end{macrocode} -% Check global setting by |\savekeys| to know whether or not to save -% the value of the key at hand. +% 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} - \XKV@ifundefined{XKV@\XKV@header save}{}{% - \expandafter\XKV@testsavekey\csname XKV@\XKV@header - save\endcsname\XKV@tkey - }% + \let\@fileswith@pti@ns\@badrequireerror + \edef\XKV@testclass{\@currname.\@currext}% % \end{macrocode} -% Save the value of a key. +% If \pf{xkeyval} is loaded by the document class, initialize +% |\@unusedoptionlist|. % \begin{macrocode} - \ifXKV@rkv - \ifXKV@sg\expandafter\global\fi\expandafter\let - \csname XKV@\XKV@header\XKV@tkey @value\endcsname\XKV@tempa - \fi + \ifx\XKV@testclass\XKV@documentclass + \let\@unusedoptionlist\XKV@classoptionslist + \XKV@ifundefined{ver@xkvltxp.sty}{}{% + \@onelevel@sanitize\@unusedoptionlist + }% + \else % \end{macrocode} -% Replace pointers by saved values. +% 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} - \expandafter\XKV@replacepointers\expandafter{\XKV@tempa}% + \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 no value was present, use the default value macro, if one exists. -% Otherwise, issue an error. +% If the option also exists in local families, add it to the list for +% later use and remove it from |\@unusedoptionlist|. % \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 + \XKV@useoption{##1}% + \XKV@addtolist@n\XKV@tempa{##1}% + }% + \expandafter\XKV@tempb + \fi }% - \else\XKV@afterfi + \expandafter\XKV@tempb\XKV@classoptionslist,\@nil,% + \fi + \fi % \end{macrocode} -% Save state in case the key executes |\setkeys| or |\XKV@cc|. +% Add current package options to the list. % \begin{macrocode} - \XKV@srstate{@\romannumeral\XKV@depth}{}% + \expandafter\XKV@addtolist@o\expandafter + \XKV@tempa\csname opt@\@currname.\@currext\endcsname % \end{macrocode} -% Execute the key. +% 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} - \csname\XKV@header\XKV@tkey\expandafter - \endcsname\expandafter{\XKV@tempa}\relax + \def\XKV@tempb{\XKV@setkeys[#1]}% + \expandafter\XKV@tempb\expandafter{\XKV@tempa}% % \end{macrocode} -% Restore the current state. +% Reset the macro created by |\DeclareOptionX*| to avoid processing +% future unknown keys using |\XKV@doxs|. % \begin{macrocode} - \XKV@srstate{}{@\romannumeral\XKV@depth}% - \fi - }% + \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@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{macro}{\XKV@useoption} +% \marg{option}\\ +% Removes an option from |\@unusedoptionlist|. % \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 +\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} -% \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. +% \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} -\long\def\XKV@replacepointers#1{% - \let\XKV@tempa\@empty - \let\XKV@resa\@empty - \XKV@r@placepointers#1\usevalue\@nil +\DeclareOptionX*{% + \PackageWarning{xkeyval}{Unknown option `\CurrentOption'}% } -\long\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\@empty - }{% - \@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 - \expandafter\expandafter\expandafter\@empty - \csname XKV@\XKV@header#2@value\endcsname +\ProcessOptionsX +% \end{macrocode} +% Reset catcodes. +% \begin{macrocode} +\XKVcatcodes +% +% \end{macrocode} +% \subsection{\texttt{keyval.tex}} +% \changes{v1.4}{2004/08/24}{Added \pf{keyval} primitives} +% \changes{v2.6 }{2008/08/10}{Added \cs{KV@def} to \texttt{keyval.tex} +% as it is used by some packages} +% 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{% +\long\def\KV@@sp@def##1##2{% + \futurelet\XKV@resa\KV@@sp@d##2\@nil\@nil#1\@nil\relax##1}% +\long\def\KV@@sp@d{% + \ifx\XKV@resa\@sptoken + \expandafter\KV@@sp@b + \else + \expandafter\KV@@sp@b\expandafter#1% + \fi}% +\long\def\KV@@sp@b#1##1 \@nil{\KV@@sp@c##1}% + } +\XKV@tempa{ } +\long\def\KV@@sp@c#1\@nil#2\relax#3{\XKV@toks{#1}\edef#3{\the\XKV@toks}} +\long\def\KV@do#1,{% + \ifx\relax#1\@empty\else + \KV@split#1==\relax + \expandafter\KV@do\fi} +\long\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} +\def\KV@def#1#2[#3]{% + \long\@namedef{KV@#1@#2@default\expandafter}\expandafter + {\csname KV@#1@#2\endcsname{#3}}% + \long\@namedef{KV@#1@#2}##1} +% +% \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}% } +% % \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. +% \subsection{\texttt{xkvutils.tex}} +% Avoid loading |xkvutils.tex| twice. % \begin{macrocode} -\def\XKV@default#1#2\@nil{% +%<*xkvutils> +\csname XKeyValUtilsLoaded\endcsname +\let\XKeyValUtilsLoaded\endinput +\edef\XKeyValUtilsCatcodes{% + \catcode`\noexpand\@\the\catcode`\@\relax + \let\noexpand\XKeyValUtilsCatcodes\relax +} +\catcode`\@=11\relax % \end{macrocode} -% Retrieve the first token in the macro. +% 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} - \expandafter\edef\expandafter\XKV@tempa - \expandafter{\expandafter\@gobble\string#1}% +\newtoks\XKV@toks +\newtoks\XKV@tempa@toks % \end{macrocode} -% Construct the name that we expect on the basis of the \pf{keyval} -% and \pf{xkeyval} syntax of default values. +% \begin{macro}{\@firstoftwo} +% \begin{macro}{\@secondoftwo} +% Two utility macros from the |latex.ltx| needed for executing +% |\XKV@ifundefined| in the sequel. % \begin{macrocode} - \edef\XKV@tempb{\XKV@header\XKV@tkey}% +\long\def\@firstoftwo#1#2{#1} +\long\def\@secondoftwo#1#2{#2} % \end{macrocode} -% Sanitize |\XKV@tempb| to reset catcodes for comparison with |\XKV@tempa|. +% \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} - \@onelevel@sanitize\XKV@tempb - \ifx\XKV@tempa\XKV@tempb +\long\def\XKV@afterfi#1\fi{\fi#1} +\long\def\XKV@afterelsefi#1\else#2\fi{\fi#1} % \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. +% \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} - \begingroup - \expandafter\def\csname\XKV@header\XKV@tkey\endcsname##1{% - \gdef\XKV@tempa{##1}% - }% - \csname\XKV@header\XKV@tkey @default\endcsname - \endgroup +\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} -% 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. +% \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{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 +\XKV@ifundefined{ver@keyval.sty}{ + \input keyval + \expandafter\def\csname ver@keyval.sty\endcsname{1999/03/16} +}{} % \end{macrocode} -% Replace the pointers. +% \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} - \expandafter\XKV@replacepointers\expandafter - {\XKV@tempa}\XKV@afterelsefi +\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} -% Save internal state. +% \end{macro} +% \end{macro} +% \begin{macro}{\XKV@for@n} +% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} +% \changes{v2.6a}{2008/08/13}{Use private scratch register} +% \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} - \XKV@srstate{@\romannumeral\XKV@depth}{}% +\long\def\XKV@for@n#1#2#3{% + \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% + \ifx#2\@empty + \XKV@for@break + \else + \expandafter\XKV@f@r + \fi + #2{#3}#1,\@nil,% +} % \end{macrocode} -% Execute the key with the (possibly changed) default value. +% \end{macro} +% \begin{macro}{\XKV@f@r} +% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} +% \changes{v2.6a}{2008/08/13}{Use private scratch register} +% \meta{cmd}\marg{function}\meta{entry}|,|\\ +% Looping macro. % \begin{macrocode} - \expandafter#1\expandafter{\XKV@tempa}\relax +\long\def\XKV@f@r#1#2#3,{% + \XKV@tempa@toks{#3}\edef#1{\the\XKV@tempa@toks}% + \ifx#1\@nnil + \expandafter\@gobbletwo + \else + #2\expandafter\XKV@f@r + \fi + #1{#2}% +} % \end{macrocode} -% Restore internal state. +% \end{macro} +% \begin{macro}{\XKV@for@break} +% \meta{text}|\@nil,|\\ +% Macro to stop the for-loop. % \begin{macrocode} - \XKV@srstate{}{@\romannumeral\XKV@depth}% - \else\XKV@afterfi +\long\def\XKV@for@break #1\@nil,{\fi} % \end{macrocode} -% Save internal state. +% \end{macro} +% \begin{macro}{\XKV@for@o} +% \meta{listcmd}\meta{cmd}\marg{function}\\ +% \meta{listcmd} is expanded once before starting the loop. % \begin{macrocode} - \XKV@srstate{@\romannumeral\XKV@depth}{}% +\long\def\XKV@for@o#1{\expandafter\XKV@for@n\expandafter{#1}} % \end{macrocode} -% Execute the key with the default value. +% \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} - \csname\XKV@header\XKV@tkey @default\endcsname\relax +\long\def\XKV@for@en#1#2#3{\XKV@f@r#2{#3}#1,\@nil,} % \end{macrocode} -% Restore the state. +% \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} - \XKV@srstate{}{@\romannumeral\XKV@depth}% - \fi +\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}{\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{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} -\def\setrmkeys{\XKV@testopta{\XKV@testoptc\XKV@setrmkeys}} +\long\def\XKV@whilist#1#2#3\fi#4{% % \end{macrocode} -% \end{macro} -% \begin{macro}{\XKV@setrmkeys} -% \oarg{na}\\ -% Submits the keys in |\XKV@rm| to |\XKV@setkeys|. +% Check whether the condition is true and start iteration. % \begin{macrocode} -\def\XKV@setrmkeys[#1]{% - \def\XKV@tempa{\XKV@setkeys[#1]}% - \expandafter\XKV@tempa\expandafter{\XKV@rm}% + #3\expandafter\XKV@wh@list#1,\@nil,\@nil\@@#2#3\fi{#4}{}\fi } % \end{macrocode} % \end{macro} -% Reset catcodes. -% \begin{macrocode} -\XKVcatcodes -% -% \end{macrocode} -% \subsection{\texttt{xkeyval.sty}} -% \changes{v1.5}{2004/09/27}{Made macros avoid expansions of options} -% Initialize the package. +% \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} -%<*xkvlatex> -\NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesPackage{xkeyval} - [2014/05/09 v2.6d package option processing (HA)] +\long\def\XKV@wh@list#1,#2\@@#3#4\fi#5#6{% % \end{macrocode} -% Initializations. Load |xkeyval.tex|, adjust some catcodes to define -% internal macros and initialize the |\DeclareOptionX*| working macro. +% Define the running \meta{cmd}. % \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 + \def#3{#1}% % \end{macrocode} -% \begin{macro}{\XKV@warn} -% \begin{macro}{\XKV@err} -% Warning and error macros. +% If we find the end of the list, stop. % \begin{macrocode} -\def\XKV@warn#1{\PackageWarning{xkeyval}{#1}} -\def\XKV@err#1{\PackageError{xkeyval}{#1}\@ehc} + \ifx#3\@nnil + \def#3{#6}\expandafter\XKV@wh@l@st + \else % \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. +% 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} -\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 - }% - }% + #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} -% If we didn't find the document class, raise an error, otherwise -% filter global options. +% \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} -\ifx\XKV@documentclass\@undefined - \XKV@err{xkeyval loaded before \protect\documentclass}% - \let\XKV@documentclass\@empty - \let\XKV@classoptionslist\@empty -\else - \let\XKV@classoptionslist\@classoptionslist +\long\def\XKV@wh@l@st#1\@@#2#3\fi#4#5{} % \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. +% \end{macro} +% \begin{macro}{\XKV@addtomacro@n} +% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} +% \changes{v2.6a}{2008/08/13}{Use private scratch register} +% \meta{macro}\marg{content}\\ +% Adds \meta{content} to \meta{macro} without expanding it. % \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 +\long\def\XKV@addtomacro@n#1#2{% + \XKV@tempa@toks\expandafter{#1#2}% + \edef#1{\the\XKV@tempa@toks}% +} % \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. +% \end{macro} +% \begin{macro}{\XKV@addtomacro@o} +% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} +% \changes{v2.6a}{2008/08/13}{Use private scratch register} +% \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@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{}% +\def\XKV@addtomacro@o#1#2{% + \expandafter\XKV@addtomacro@n\expandafter#1\expandafter{#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} -% \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{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\DeclareOptionX{% - \let\@fileswith@pti@ns\@badrequireerror - \XKV@ifstar\XKV@dox\XKV@d@x +\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@dox} -% This macro defines |\XKV@doxs| to be used for unknown options. +% \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} -\long\def\XKV@dox#1{\XKV@toks{#1}\edef\XKV@doxs{\the\XKV@toks}} +\def\XKV@addtolist@x#1#2{\edef#1{#1\ifx#1\@empty\else,\fi#2}} % \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{macro}{\@selective@sanitize} +% \begin{macro}{\@s@lective@sanitize} +% \changes{v2.5a}{2005/05/31}{Added missing `\%'} +% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} +% \changes{v2.6a}{2008/08/13}{Use private scratch register} +% \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\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\@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\XKV@tempa@toks\expandafter{#3}% + \expandafter\endgroup\expandafter\toks@\expandafter{\the\XKV@tempa@toks}% + \edef#3{\the\toks@}% } -\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{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\ExecuteOptionsX{\XKV@stfalse\XKV@plfalse\XKV@t@stopte\XKV@setkeys} +\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}{\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{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\ProcessOptionsX{\XKV@plfalse\XKV@testopte\XKV@pox} +\long\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@pox} -% \oarg{na}\\ -% Workhorse for |\ProcessOptionsX| and |\ProcessOptionsX*|. +% \begin{macro}{\XKV@checksanitizeb} +% \marg{content}\meta{cmd}\\ +% Similar to |\XKV@checksanitizea|, but only checks commas. % \begin{macrocode} -\def\XKV@pox[#1]{% - \let\XKV@tempa\@empty +\def\XKV@checksanitizeb#1#2{% + \XKV@ch@cksanitize{#1}#2,% + \ifin@\@selective@sanitize[0],#2\fi +} % \end{macrocode} -% Set |\XKV@inpox|: indicates that we are in |\ProcessOptionsX| to -% invoke a special routine in |\XKV@s@tkeys|. +% \end{macro} +% \begin{macro}{\XKV@ch@cksanitize} +% \changes{v1.8b}{2004/12/22}{Fixed bug for key value \cs{@empty}} +% \changes{v2.6 }{2008/08/10}{protecting assignments from \#} +% \changes{v2.6a}{2008/08/13}{Use private scratch register} +% \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} - \XKV@inpoxtrue +\long\def\XKV@ch@cksanitize#1#2#3{% + \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% + \@onelevel@sanitize#2% % \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|. +% Check whether there is at least one |=| present. % \begin{macrocode} - \let\@fileswith@pti@ns\@badrequireerror - \edef\XKV@testclass{\@currname.\@currext}% + \@expandtwoargs\in@#3{#2}% + \ifin@ % \end{macrocode} -% If \pf{xkeyval} is loaded by the document class, initialize -% |\@unusedoptionlist|. +% 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} - \ifx\XKV@testclass\XKV@documentclass - \let\@unusedoptionlist\XKV@classoptionslist - \XKV@ifundefined{ver@xkvltxp.sty}{}{% - \@onelevel@sanitize\@unusedoptionlist + \long\def#2##1#3##2\@nil{% + \XKV@tempa@toks{##2}\edef#2{\the\XKV@tempa@toks}% + \ifx#2\@empty\else\in@false\fi }% - \else + #2#1#3\@nil + \fi + \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% +} % \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. +% \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} - \ifXKV@st - \def\XKV@tempb##1,{% - \def\CurrentOption{##1}% - \ifx\CurrentOption\@nnil\else - \XKV@g@tkeyname##1=\@nil\CurrentOption - \XKV@key@if@ndefined{\CurrentOption}{}{% +\def\XKV@merge#1#2#3{% + \XKV@checksanitizea{#2}\XKV@tempa % \end{macrocode} -% If the option also exists in local families, add it to the list for -% later use and remove it from |\@unusedoptionlist|. +% Start the loop over the new presets. At every iteration, one new preset +% will be compared with old presets. % \begin{macrocode} - \XKV@useoption{##1}% - \XKV@addtolist@n\XKV@tempa{##1}% - }% - \expandafter\XKV@tempb - \fi - }% - \expandafter\XKV@tempb\XKV@classoptionslist,\@nil,% - \fi - \fi + \XKV@for@o\XKV@tempa\XKV@tempa{% + \XKV@pltrue % \end{macrocode} -% Add current package options to the list. +% Retrieve the key name of the new item at hand. % \begin{macrocode} - \expandafter\XKV@addtolist@o\expandafter - \XKV@tempa\csname opt@\@currname.\@currext\endcsname + #3\XKV@tempa\XKV@tempb % \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. +% Store the (partially updated) old list in a temp macro and empty +% the original macro. % \begin{macrocode} - \def\XKV@tempb{\XKV@setkeys[#1]}% - \expandafter\XKV@tempb\expandafter{\XKV@tempa}% + \let\XKV@tempc#1% + \let#1\@empty % \end{macrocode} -% Reset the macro created by |\DeclareOptionX*| to avoid processing -% future unknown keys using |\XKV@doxs|. +% Start a loop over the old list. % \begin{macrocode} - \let\XKV@doxs\relax + \XKV@for@o\XKV@tempc\XKV@tempc{% % \end{macrocode} -% Reset the |\XKV@rm| macro to avoid processing remaining options -% with |\setrmkeys|. +% Retrieve the key name of the old key at hand. % \begin{macrocode} - \let\XKV@rm\@empty + #3\XKV@tempc\XKV@tempd + \ifx\XKV@tempb\XKV@tempd % \end{macrocode} -% Reset |\ifXKV@inpox|: not in |\ProcessOptionsX| anymore. +% 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@inpoxfalse + \XKV@plfalse + \XKV@addtolist@o#1\XKV@tempa + \else % \end{macrocode} -% Reset |\@fileswith@pti@ns| to allow loading of classes or packages -% again. +% If the key names are not equal, then just append the current item +% to the list. % \begin{macrocode} - \let\@fileswith@pti@ns\@@fileswith@pti@ns - \AtEndOfPackage{\let\@unprocessedoptions\relax}% -} + \XKV@addtolist@o#1\XKV@tempc + \fi + }% % \end{macrocode} -% \end{macro} -% \begin{macro}{\XKV@useoption} -% \marg{option}\\ -% Removes an option from |\@unusedoptionlist|. +% 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} -\def\XKV@useoption#1{% - \def\XKV@resa{#1}% - \XKV@ifundefined{ver@xkvltxp.sty}{}{% - \@onelevel@sanitize\XKV@resa + \ifXKV@pl\XKV@addtolist@o#1\XKV@tempa\fi }% - \@expandtwoargs\@removeelement{\XKV@resa}% - {\@unusedoptionlist}\@unusedoptionlist +% \end{macrocode} +% If requested, save the new list globally. +% \begin{macrocode} + \ifXKV@st\global\let#1#1\fi } % \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{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} -\DeclareOptionX*{% - \PackageWarning{xkeyval}{Unknown option `\CurrentOption'}% -} -\ProcessOptionsX +\def\XKV@delete#1#2#3{% % \end{macrocode} -% Reset catcodes. +% Sanitize comma's. % \begin{macrocode} -\XKVcatcodes -% + \XKV@checksanitizeb{#2}\XKV@tempa % \end{macrocode} -% \subsection{\texttt{keyval.tex}} -% \changes{v1.4}{2004/08/24}{Added \pf{keyval} primitives} -% \changes{v2.6 }{2008/08/10}{Added \cs{KV@def} to \texttt{keyval.tex} -% as it is used by some packages} -% 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. +% Copy the current list and make the original empty. % \begin{macrocode} -%<*xkvkeyval> -%% -%% Based on keyval.sty. -%% -\def\XKV@tempa#1{% -\long\def\KV@@sp@def##1##2{% - \futurelet\XKV@resa\KV@@sp@d##2\@nil\@nil#1\@nil\relax##1}% -\long\def\KV@@sp@d{% - \ifx\XKV@resa\@sptoken - \expandafter\KV@@sp@b - \else - \expandafter\KV@@sp@b\expandafter#1% - \fi}% -\long\def\KV@@sp@b#1##1 \@nil{\KV@@sp@c##1}% - } -\XKV@tempa{ } -\long\def\KV@@sp@c#1\@nil#2\relax#3{\XKV@toks{#1}\edef#3{\the\XKV@toks}} -\long\def\KV@do#1,{% - \ifx\relax#1\@empty\else - \KV@split#1==\relax - \expandafter\KV@do\fi} -\long\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} -\def\KV@def#1#2[#3]{% - \long\@namedef{KV@#1@#2@default\expandafter}\expandafter - {\csname KV@#1@#2\endcsname{#3}}% - \long\@namedef{KV@#1@#2}##1} -% + \let\XKV@tempb#1% + \let#1\@empty % \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|. +% Run over the current list. % \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}% + \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} +% Finalize. +% \begin{macrocode} +\XKeyValUtilsCatcodes +% % \end{macrocode} % \subsection{\texttt{xkvview.sty}} % This section provides a small utility for package developers. It @@ -4700,7 +4727,14 @@ macro. \PrintChangesX\PrintIndexX %% Based on latex.ltx. %% \NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesPackage{xkvltxp}[2004/12/13 v1.2 LaTeX2e kernel patch (HA)] +\ProvidesPackage{xkvltxp}[2014/05/25 v1.3 LaTeX2e kernel patch (HA)] +% \end{macrocode} +% Load utilities needed in this package. +% \begin{macrocode} +\input xkvutils +% \end{macrocode} +% Start redefining internal \LaTeX\ macros. +% \begin{macrocode} \def\@pass@ptions#1#2#3{% \def\reserved@a{#2}% \def\reserved@b{\CurrentOption}% @@ -4736,11 +4770,15 @@ macro. \PrintChangesX\PrintIndexX \@unusedoptionlist\@unusedoptionlist \csname ds@\CurrentOption\endcsname } +% \end{macrocode} +% \begin{macro}{\@fileswith@pti@ns} +% \changes{v1.3}{2014/05/25}{Added code to remove spaces around options} +% \begin{macrocode} \def\@fileswith@pti@ns#1[#2]#3[#4]{% + \XKV@sp@deflist\XKV@resb{#2}% \ifx#1\@clsextension \ifx\@classoptionslist\relax - \@temptokena{#2}% - \xdef\@classoptionslist{\the\@temptokena}% + \let\@classoptionslist\XKV@resb \def\reserved@a{% \@onefilewithoptions#3[#2][#4]#1% \@documentclasshook}% @@ -4749,12 +4787,11 @@ macro. \PrintChangesX\PrintIndexX \@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 + [\XKV@resb][#4]\noexpand\@pkgextension \fi \expandafter\reserved@b \fi}% @@ -4762,6 +4799,9 @@ macro. \PrintChangesX\PrintIndexX \edef\reserved@a{\expandafter\reserved@b\reserved@a,\@nil,}% \fi \reserved@a} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} \let\@@fileswith@pti@ns\@fileswith@pti@ns % % \end{macrocode} diff --git a/Master/texmf-dist/tex/generic/xkeyval/keyval.tex b/Master/texmf-dist/tex/generic/xkeyval/keyval.tex index 845262148f9..2e20848268c 100644 --- a/Master/texmf-dist/tex/generic/xkeyval/keyval.tex +++ b/Master/texmf-dist/tex/generic/xkeyval/keyval.tex @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% %% %% Based on keyval.sty. diff --git a/Master/texmf-dist/tex/generic/xkeyval/pst-xkey.tex b/Master/texmf-dist/tex/generic/xkeyval/pst-xkey.tex index 3fa4f9e7e37..c97613157dd 100644 --- a/Master/texmf-dist/tex/generic/xkeyval/pst-xkey.tex +++ b/Master/texmf-dist/tex/generic/xkeyval/pst-xkey.tex @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \csname PSTXKeyLoaded\endcsname \let\PSTXKeyLoaded\endinput diff --git a/Master/texmf-dist/tex/generic/xkeyval/xkeyval.tex b/Master/texmf-dist/tex/generic/xkeyval/xkeyval.tex index 9b956a077ef..954450c1685 100644 --- a/Master/texmf-dist/tex/generic/xkeyval/xkeyval.tex +++ b/Master/texmf-dist/tex/generic/xkeyval/xkeyval.tex @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \csname XKeyValLoaded\endcsname \let\XKeyValLoaded\endinput @@ -46,8 +46,7 @@ \catcode`\=12\relax \catcode`\,12\relax \catcode`\:12\relax -\newtoks\XKV@toks -\newtoks\XKV@tempa@toks +\input xkvutils \newcount\XKV@depth \newif\ifXKV@st \newif\ifXKV@sg @@ -58,235 +57,12 @@ \newif\ifXKV@preset \let\XKV@rm\@empty \ifx\ProvidesFile\@undefined - \message{2014/05/09 v2.6d key=value parser (HA)} + \message{2014/05/25 v2.7 key=value parser (HA)} \input xkvtxhdr \else - \ProvidesFile{xkeyval.tex}[2014/05/09 v2.6d key=value parser (HA)] + \ProvidesFile{xkeyval.tex}[2014/05/25 v2.7 key=value parser (HA)] \@addtofilelist{xkeyval.tex} \fi -\long\def\@firstoftwo#1#2{#1} -\long\def\@secondoftwo#1#2{#2} -\long\def\XKV@afterfi#1\fi{\fi#1} -\long\def\XKV@afterelsefi#1\else#2\fi{\fi#1} -\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 -\XKV@ifundefined{ver@keyval.sty}{ - \input keyval - \expandafter\def\csname ver@keyval.sty\endcsname{1999/03/16} -}{} -\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% -} -\long\def\XKV@for@n#1#2#3{% - \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% - \ifx#2\@empty - \XKV@for@break - \else - \expandafter\XKV@f@r - \fi - #2{#3}#1,\@nil,% -} -\long\def\XKV@f@r#1#2#3,{% - \XKV@tempa@toks{#3}\edef#1{\the\XKV@tempa@toks}% - \ifx#1\@nnil - \expandafter\@gobbletwo - \else - #2\expandafter\XKV@f@r - \fi - #1{#2}% -} -\long\def\XKV@for@break #1\@nil,{\fi} -\long\def\XKV@for@o#1{\expandafter\XKV@for@n\expandafter{#1}} -\long\def\XKV@for@en#1#2#3{\XKV@f@r#2{#3}#1,\@nil,} -\long\def\XKV@for@eo#1#2#3{% - \def#2{\XKV@f@r#2{#3}}\expandafter#2#1,\@nil,% -} -\long\def\XKV@whilist#1#2#3\fi#4{% - #3\expandafter\XKV@wh@list#1,\@nil,\@nil\@@#2#3\fi{#4}{}\fi -} -\long\def\XKV@wh@list#1,#2\@@#3#4\fi#5#6{% - \def#3{#1}% - \ifx#3\@nnil - \def#3{#6}\expandafter\XKV@wh@l@st - \else - #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}% -} -\long\def\XKV@wh@l@st#1\@@#2#3\fi#4#5{} -\long\def\XKV@addtomacro@n#1#2{% - \XKV@tempa@toks\expandafter{#1#2}% - \edef#1{\the\XKV@tempa@toks}% -} -\def\XKV@addtomacro@o#1#2{% - \expandafter\XKV@addtomacro@n\expandafter#1\expandafter{#2}% -} -\def\XKV@addtolist@n#1#2{% - \ifx#1\@empty - \XKV@addtomacro@n#1{#2}% - \else - \XKV@addtomacro@n#1{,#2}% - \fi -} -\def\XKV@addtolist@o#1#2{% - \ifx#1\@empty - \XKV@addtomacro@o#1#2% - \else - \XKV@addtomacro@o#1{\expandafter,#2}% - \fi -} -\def\XKV@addtolist@x#1#2{\edef#1{#1\ifx#1\@empty\else,\fi#2}} -\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\XKV@tempa@toks\expandafter{#3}% - \expandafter\endgroup\expandafter\toks@\expandafter{\the\XKV@tempa@toks}% - \edef#3{\the\toks@}% -} -\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 -} -\long\def\XKV@checksanitizea#1#2{% - \XKV@ch@cksanitize{#1}#2=% - \ifin@\else\XKV@ch@cksanitize{#1}#2,\fi - \ifin@\@selective@sanitize[0]{,=}#2\fi -} -\def\XKV@checksanitizeb#1#2{% - \XKV@ch@cksanitize{#1}#2,% - \ifin@\@selective@sanitize[0],#2\fi -} -\long\def\XKV@ch@cksanitize#1#2#3{% - \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% - \@onelevel@sanitize#2% - \@expandtwoargs\in@#3{#2}% - \ifin@ - \long\def#2##1#3##2\@nil{% - \XKV@tempa@toks{##2}\edef#2{\the\XKV@tempa@toks}% - \ifx#2\@empty\else\in@false\fi - }% - #2#1#3\@nil - \fi - \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% -} -\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 -} -\def\XKV@merge#1#2#3{% - \XKV@checksanitizea{#2}\XKV@tempa - \XKV@for@o\XKV@tempa\XKV@tempa{% - \XKV@pltrue - #3\XKV@tempa\XKV@tempb - \let\XKV@tempc#1% - \let#1\@empty - \XKV@for@o\XKV@tempc\XKV@tempc{% - #3\XKV@tempc\XKV@tempd - \ifx\XKV@tempb\XKV@tempd - \XKV@plfalse - \XKV@addtolist@o#1\XKV@tempa - \else - \XKV@addtolist@o#1\XKV@tempc - \fi - }% - \ifXKV@pl\XKV@addtolist@o#1\XKV@tempa\fi - }% - \ifXKV@st\global\let#1#1\fi -} -\def\XKV@delete#1#2#3{% - \XKV@checksanitizeb{#2}\XKV@tempa - \let\XKV@tempb#1% - \let#1\@empty - \XKV@for@o\XKV@tempb\XKV@tempb{% - #3\XKV@tempb\XKV@tempc - \@expandtwoargs\in@{,\XKV@tempc,}{,\XKV@tempa,}% - \ifin@\else\XKV@addtolist@o#1\XKV@tempb\fi - }% - \ifXKV@st\global\let#1#1\fi -} \def\XKV@warn#1{\message{xkeyval warning: #1}} \def\XKV@err#1{\errmessage{xkeyval error: #1}} \def\KV@errx{\XKV@err} diff --git a/Master/texmf-dist/tex/generic/xkeyval/xkvex1.tex b/Master/texmf-dist/tex/generic/xkeyval/xkvex1.tex index a6c24b244a0..fa3175e5244 100644 --- a/Master/texmf-dist/tex/generic/xkeyval/xkvex1.tex +++ b/Master/texmf-dist/tex/generic/xkeyval/xkvex1.tex @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \input xkeyval diff --git a/Master/texmf-dist/tex/generic/xkeyval/xkvex2.tex b/Master/texmf-dist/tex/generic/xkeyval/xkvex2.tex index 8616eb81f63..f1faa18d77d 100644 --- a/Master/texmf-dist/tex/generic/xkeyval/xkvex2.tex +++ b/Master/texmf-dist/tex/generic/xkeyval/xkvex2.tex @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \documentclass{article} \usepackage{xkeyval} diff --git a/Master/texmf-dist/tex/generic/xkeyval/xkvex3.tex b/Master/texmf-dist/tex/generic/xkeyval/xkvex3.tex index a21a493e9aa..3af72ff69cb 100644 --- a/Master/texmf-dist/tex/generic/xkeyval/xkvex3.tex +++ b/Master/texmf-dist/tex/generic/xkeyval/xkvex3.tex @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% %% keyi will set \keyi in xkveca.cls %% keyvi will set \keyvi in xkveca.cls and xkvesc.sty will pick diff --git a/Master/texmf-dist/tex/generic/xkeyval/xkvex4.tex b/Master/texmf-dist/tex/generic/xkeyval/xkvex4.tex index a7cdfc45a6d..916818b922f 100644 --- a/Master/texmf-dist/tex/generic/xkeyval/xkvex4.tex +++ b/Master/texmf-dist/tex/generic/xkeyval/xkvex4.tex @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% %% Load LaTeX kernel macros patch \RequirePackage{xkvltxp} diff --git a/Master/texmf-dist/tex/generic/xkeyval/xkvtxhdr.tex b/Master/texmf-dist/tex/generic/xkeyval/xkvtxhdr.tex index f6933df422b..a3df28495f4 100644 --- a/Master/texmf-dist/tex/generic/xkeyval/xkvtxhdr.tex +++ b/Master/texmf-dist/tex/generic/xkeyval/xkvtxhdr.tex @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% %% %% Taken from latex.ltx. diff --git a/Master/texmf-dist/tex/generic/xkeyval/xkvutils.tex b/Master/texmf-dist/tex/generic/xkeyval/xkvutils.tex new file mode 100644 index 00000000000..5eb5130f617 --- /dev/null +++ b/Master/texmf-dist/tex/generic/xkeyval/xkvutils.tex @@ -0,0 +1,271 @@ +%% +%% This is file `xkvutils.tex', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% xkeyval.dtx (with options: `xkvutils') +%% +%% --------------------------------------- +%% Copyright (C) 2004-2014 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, xkvutils.tex, 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, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. +%% +\csname XKeyValUtilsLoaded\endcsname +\let\XKeyValUtilsLoaded\endinput +\edef\XKeyValUtilsCatcodes{% + \catcode`\noexpand\@\the\catcode`\@\relax + \let\noexpand\XKeyValUtilsCatcodes\relax +} +\catcode`\@=11\relax +\newtoks\XKV@toks +\newtoks\XKV@tempa@toks +\long\def\@firstoftwo#1#2{#1} +\long\def\@secondoftwo#1#2{#2} +\long\def\XKV@afterfi#1\fi{\fi#1} +\long\def\XKV@afterelsefi#1\else#2\fi{\fi#1} +\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 +\XKV@ifundefined{ver@keyval.sty}{ + \input keyval + \expandafter\def\csname ver@keyval.sty\endcsname{1999/03/16} +}{} +\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% +} +\long\def\XKV@for@n#1#2#3{% + \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% + \ifx#2\@empty + \XKV@for@break + \else + \expandafter\XKV@f@r + \fi + #2{#3}#1,\@nil,% +} +\long\def\XKV@f@r#1#2#3,{% + \XKV@tempa@toks{#3}\edef#1{\the\XKV@tempa@toks}% + \ifx#1\@nnil + \expandafter\@gobbletwo + \else + #2\expandafter\XKV@f@r + \fi + #1{#2}% +} +\long\def\XKV@for@break #1\@nil,{\fi} +\long\def\XKV@for@o#1{\expandafter\XKV@for@n\expandafter{#1}} +\long\def\XKV@for@en#1#2#3{\XKV@f@r#2{#3}#1,\@nil,} +\long\def\XKV@for@eo#1#2#3{% + \def#2{\XKV@f@r#2{#3}}\expandafter#2#1,\@nil,% +} +\long\def\XKV@whilist#1#2#3\fi#4{% + #3\expandafter\XKV@wh@list#1,\@nil,\@nil\@@#2#3\fi{#4}{}\fi +} +\long\def\XKV@wh@list#1,#2\@@#3#4\fi#5#6{% + \def#3{#1}% + \ifx#3\@nnil + \def#3{#6}\expandafter\XKV@wh@l@st + \else + #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}% +} +\long\def\XKV@wh@l@st#1\@@#2#3\fi#4#5{} +\long\def\XKV@addtomacro@n#1#2{% + \XKV@tempa@toks\expandafter{#1#2}% + \edef#1{\the\XKV@tempa@toks}% +} +\def\XKV@addtomacro@o#1#2{% + \expandafter\XKV@addtomacro@n\expandafter#1\expandafter{#2}% +} +\def\XKV@addtolist@n#1#2{% + \ifx#1\@empty + \XKV@addtomacro@n#1{#2}% + \else + \XKV@addtomacro@n#1{,#2}% + \fi +} +\def\XKV@addtolist@o#1#2{% + \ifx#1\@empty + \XKV@addtomacro@o#1#2% + \else + \XKV@addtomacro@o#1{\expandafter,#2}% + \fi +} +\def\XKV@addtolist@x#1#2{\edef#1{#1\ifx#1\@empty\else,\fi#2}} +\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\XKV@tempa@toks\expandafter{#3}% + \expandafter\endgroup\expandafter\toks@\expandafter{\the\XKV@tempa@toks}% + \edef#3{\the\toks@}% +} +\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 +} +\long\def\XKV@checksanitizea#1#2{% + \XKV@ch@cksanitize{#1}#2=% + \ifin@\else\XKV@ch@cksanitize{#1}#2,\fi + \ifin@\@selective@sanitize[0]{,=}#2\fi +} +\def\XKV@checksanitizeb#1#2{% + \XKV@ch@cksanitize{#1}#2,% + \ifin@\@selective@sanitize[0],#2\fi +} +\long\def\XKV@ch@cksanitize#1#2#3{% + \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% + \@onelevel@sanitize#2% + \@expandtwoargs\in@#3{#2}% + \ifin@ + \long\def#2##1#3##2\@nil{% + \XKV@tempa@toks{##2}\edef#2{\the\XKV@tempa@toks}% + \ifx#2\@empty\else\in@false\fi + }% + #2#1#3\@nil + \fi + \XKV@tempa@toks{#1}\edef#2{\the\XKV@tempa@toks}% +} +\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 +} +\def\XKV@merge#1#2#3{% + \XKV@checksanitizea{#2}\XKV@tempa + \XKV@for@o\XKV@tempa\XKV@tempa{% + \XKV@pltrue + #3\XKV@tempa\XKV@tempb + \let\XKV@tempc#1% + \let#1\@empty + \XKV@for@o\XKV@tempc\XKV@tempc{% + #3\XKV@tempc\XKV@tempd + \ifx\XKV@tempb\XKV@tempd + \XKV@plfalse + \XKV@addtolist@o#1\XKV@tempa + \else + \XKV@addtolist@o#1\XKV@tempc + \fi + }% + \ifXKV@pl\XKV@addtolist@o#1\XKV@tempa\fi + }% + \ifXKV@st\global\let#1#1\fi +} +\def\XKV@delete#1#2#3{% + \XKV@checksanitizeb{#2}\XKV@tempa + \let\XKV@tempb#1% + \let#1\@empty + \XKV@for@o\XKV@tempb\XKV@tempb{% + #3\XKV@tempb\XKV@tempc + \@expandtwoargs\in@{,\XKV@tempc,}{,\XKV@tempa,}% + \ifin@\else\XKV@addtolist@o#1\XKV@tempb\fi + }% + \ifXKV@st\global\let#1#1\fi +} +\XKeyValUtilsCatcodes +\endinput +%% +%% End of file `xkvutils.tex'. diff --git a/Master/texmf-dist/tex/latex/xkeyval/pst-xkey.sty b/Master/texmf-dist/tex/latex/xkeyval/pst-xkey.sty index 4f0fb97c510..95e60c218c5 100644 --- a/Master/texmf-dist/tex/latex/xkeyval/pst-xkey.sty +++ b/Master/texmf-dist/tex/latex/xkeyval/pst-xkey.sty @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \NeedsTeXFormat{LaTeX2e}[1995/12/01] \ProvidesPackage{pst-xkey} diff --git a/Master/texmf-dist/tex/latex/xkeyval/xkeyval.sty b/Master/texmf-dist/tex/latex/xkeyval/xkeyval.sty index 727ed8802af..2a56d2b7b2a 100644 --- a/Master/texmf-dist/tex/latex/xkeyval/xkeyval.sty +++ b/Master/texmf-dist/tex/latex/xkeyval/xkeyval.sty @@ -24,18 +24,18 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \NeedsTeXFormat{LaTeX2e}[1995/12/01] \ProvidesPackage{xkeyval} - [2014/05/09 v2.6d package option processing (HA)] + [2014/05/25 v2.7 package option processing (HA)] \ifx\XKeyValLoaded\endinput\else\input xkeyval \fi \edef\XKVcatcodes{% \catcode`\noexpand\=\the\catcode`\=\relax diff --git a/Master/texmf-dist/tex/latex/xkeyval/xkveca.cls b/Master/texmf-dist/tex/latex/xkeyval/xkveca.cls index b4f1dc94405..0eb58fe1d79 100644 --- a/Master/texmf-dist/tex/latex/xkeyval/xkveca.cls +++ b/Master/texmf-dist/tex/latex/xkeyval/xkveca.cls @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \ProvidesClass{xkveca} \usepackage{xkeyval} diff --git a/Master/texmf-dist/tex/latex/xkeyval/xkvecb.cls b/Master/texmf-dist/tex/latex/xkeyval/xkvecb.cls index 595a171ad77..8c7280b4e8a 100644 --- a/Master/texmf-dist/tex/latex/xkeyval/xkvecb.cls +++ b/Master/texmf-dist/tex/latex/xkeyval/xkvecb.cls @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \ProvidesClass{xkvecb} %% pass any unknown option to article diff --git a/Master/texmf-dist/tex/latex/xkeyval/xkvesa.sty b/Master/texmf-dist/tex/latex/xkeyval/xkvesa.sty index a4545d865d8..5bdbd2f42b4 100644 --- a/Master/texmf-dist/tex/latex/xkeyval/xkvesa.sty +++ b/Master/texmf-dist/tex/latex/xkeyval/xkvesa.sty @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \ProvidesPackage{xkvesa} \let\keyia\@empty diff --git a/Master/texmf-dist/tex/latex/xkeyval/xkvesb.sty b/Master/texmf-dist/tex/latex/xkeyval/xkvesb.sty index 305959bf4dc..1f9e3ab9916 100644 --- a/Master/texmf-dist/tex/latex/xkeyval/xkvesb.sty +++ b/Master/texmf-dist/tex/latex/xkeyval/xkvesb.sty @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \ProvidesPackage{xkvesb} \let\keyiii\@empty diff --git a/Master/texmf-dist/tex/latex/xkeyval/xkvesc.sty b/Master/texmf-dist/tex/latex/xkeyval/xkvesc.sty index 0747aa82178..752ba227605 100644 --- a/Master/texmf-dist/tex/latex/xkeyval/xkvesc.sty +++ b/Master/texmf-dist/tex/latex/xkeyval/xkvesc.sty @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \ProvidesPackage{xkvesc} %% redefine \keyvi when keyvi option is specified in \documentclass diff --git a/Master/texmf-dist/tex/latex/xkeyval/xkvltxp.sty b/Master/texmf-dist/tex/latex/xkeyval/xkvltxp.sty index 0480a11ce2b..e5be8cb052e 100644 --- a/Master/texmf-dist/tex/latex/xkeyval/xkvltxp.sty +++ b/Master/texmf-dist/tex/latex/xkeyval/xkvltxp.sty @@ -24,20 +24,21 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% %% %% Based on latex.ltx. %% \NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesPackage{xkvltxp}[2004/12/13 v1.2 LaTeX2e kernel patch (HA)] +\ProvidesPackage{xkvltxp}[2014/05/25 v1.3 LaTeX2e kernel patch (HA)] +\input xkvutils \def\@pass@ptions#1#2#3{% \def\reserved@a{#2}% \def\reserved@b{\CurrentOption}% @@ -74,10 +75,10 @@ \csname ds@\CurrentOption\endcsname } \def\@fileswith@pti@ns#1[#2]#3[#4]{% + \XKV@sp@deflist\XKV@resb{#2}% \ifx#1\@clsextension \ifx\@classoptionslist\relax - \@temptokena{#2}% - \xdef\@classoptionslist{\the\@temptokena}% + \let\@classoptionslist\XKV@resb \def\reserved@a{% \@onefilewithoptions#3[#2][#4]#1% \@documentclasshook}% @@ -86,12 +87,11 @@ \@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 + [\XKV@resb][#4]\noexpand\@pkgextension \fi \expandafter\reserved@b \fi}% diff --git a/Master/texmf-dist/tex/latex/xkeyval/xkvview.sty b/Master/texmf-dist/tex/latex/xkeyval/xkvview.sty index 379b48aa3bb..c2912f962f3 100644 --- a/Master/texmf-dist/tex/latex/xkeyval/xkvview.sty +++ b/Master/texmf-dist/tex/latex/xkeyval/xkvview.sty @@ -24,14 +24,14 @@ %% %% 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. +%% xkvltxp.sty, xkvutils.tex, 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. +%% xkvltxp.sty, xkvtxhdr.tex, xkvutils.tex, pst-xkey.dtx and xkeyval.dtx. %% \NeedsTeXFormat{LaTeX2e}[1995/12/01] \ProvidesPackage{xkvview}% -- cgit v1.2.3