summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/keycommand
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-03-29 23:36:00 +0000
committerKarl Berry <karl@freefriends.org>2010-03-29 23:36:00 +0000
commit899f74725ef26bec837b6c3564ffd0108c6db6ec (patch)
treed724bed579e96e5450a9bcad843be475819fa33e /Master/texmf-dist/source/latex/keycommand
parent6cd753d70a545457376c1684169e48ca537f34ac (diff)
keycommand update (29mar10)
git-svn-id: svn://tug.org/texlive/trunk@17616 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/keycommand')
-rw-r--r--Master/texmf-dist/source/latex/keycommand/keycommand.drv59
-rw-r--r--Master/texmf-dist/source/latex/keycommand/keycommand.dtx1013
-rw-r--r--Master/texmf-dist/source/latex/keycommand/keycommand.ins21
3 files changed, 711 insertions, 382 deletions
diff --git a/Master/texmf-dist/source/latex/keycommand/keycommand.drv b/Master/texmf-dist/source/latex/keycommand/keycommand.drv
new file mode 100644
index 00000000000..2ad4f24cd05
--- /dev/null
+++ b/Master/texmf-dist/source/latex/keycommand/keycommand.drv
@@ -0,0 +1,59 @@
+%%
+%% This is file `keycommand.drv',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% keycommand.dtx (with options: `driver')
+%%
+%% This is a generated file.
+%%
+%% keycommand : key-value interface for commands and environments in LaTeX [v3.0 2010/03/28]
+%%
+%% 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
+%%
+%% This work consists of the main source file keycommand.dtx
+%% and the derived files
+%% keycommand.sty, keycommand.pdf, keycommand.ins,
+%% keycommand-example.tex
+%%
+%% keycommand : an easy way to define commands with optional keys
+%% Copyright (C) 2009-2010 by Florent Chervet <florent.chervet@free.fr>
+%%
+\edef\thisfile{\jobname}
+\def\thisinfo{key-value interface for commands and environments in \LaTeX.}
+\def\thisdate{2010/03/28}
+\def\thisversion{3.0}
+\let\loadclass\LoadClass
+\def\LoadClass#1{\loadclass[abstracton]{scrartcl}\let\scrmaketitle\maketitle\AtEndOfClass{\let\maketitle\scrmaketitle}}
+\documentclass[a4paper,oneside]{ltxdoc}
+\usepackage[latin9]{inputenc}
+\usepackage[american]{babel}
+\usepackage[T1]{fontenc}
+\usepackage{etex,holtxdoc,geometry,tocloft,graphicx,xspace,fancyhdr,color,bbding,embedfile,framed,multirow,txfonts,makecell,enumitem,arydshln}
+\CodelineNumbered
+\usepackage{keyval}\makeatletter\let\keyval@setkeys\setkeys\makeatother
+\usepackage{xkeyval}\let\xsetkeys\setkeys
+\usepackage{kvsetkeys}
+\usepackage{fancyvrb}
+\lastlinefit999
+\geometry{top=2cm,headheight=1cm,headsep=.3cm,bottom=1.4cm,footskip=.5cm,left=2.5cm,right=1cm}
+\hypersetup{%
+ pdftitle={The keycommand package},
+ pdfsubject={An e-TeX package for more useful tools for LaTeX package writers},
+ pdfauthor={Florent CHERVET},
+ colorlinks,linkcolor=reflink,
+ pdfstartview={FitH},
+ pdfkeywords={tex, e-tex, latex, package, keys, keycommand, newcommand, keyval, kvsetkeys, programming},
+ bookmarksopen=true,bookmarksopenlevel=2}
+\embedfile{\thisfile.dtx}
+\begin{document}
+ \DocInput{\thisfile.dtx}
+\end{document}
+\endinput
+%%
+%% End of file `keycommand.drv'.
diff --git a/Master/texmf-dist/source/latex/keycommand/keycommand.dtx b/Master/texmf-dist/source/latex/keycommand/keycommand.dtx
index 05585675a2e..c5459cebc58 100644
--- a/Master/texmf-dist/source/latex/keycommand/keycommand.dtx
+++ b/Master/texmf-dist/source/latex/keycommand/keycommand.dtx
@@ -1,5 +1,5 @@
% \iffalse meta-comment
-% keycommand : an easy way to define commands with optional keys |v2.z 2009/08/26]
+% keycommand : key-value interface for commands and environments in LaTeX v3.0 2010/03/28]
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
@@ -23,7 +23,7 @@
%
% Documentation:
% (pdf)latex keycommand.dtx
-% Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
+% Copyright (C) 2009-2010 by Florent Chervet <florent.chervet@free.fr>
%<*ignore>
\begingroup
\def\x{LaTeX2e}%
@@ -37,7 +37,7 @@
\input docstrip.tex
\Msg{************************************************************************}
\Msg{* Installation}
-\Msg{* Package: keycommand 2009/07/22 v1.0 an easy way to define commands with optional keys}
+\Msg{* Package: keycommand 2010/03/28 v3.0 key-value interface for commands and environments in LaTeX}
\Msg{************************************************************************}
\keepsilent
@@ -48,7 +48,7 @@
This is a generated file.
-keycommand : an easy way to define commands with optional keys [v2.z 2009/08/26]
+keycommand : key-value interface for commands and environments in LaTeX [v3.0 2010/03/28]
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either
@@ -62,15 +62,19 @@ and the derived files
keycommand-example.tex
keycommand : an easy way to define commands with optional keys
-Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
+Copyright (C) 2009-2010 by Florent Chervet <florent.chervet@free.fr>
\endpreamble
\let\MetaPrefix\DoubleperCent
\generate{%
- \file{keycommand.ins}{\from{keycommand.dtx}{install}}%
- \file{keycommand.sty}{\from{keycommand.dtx}{package}}%
- \file{keycommand-example.tex}{\from{keycommand.dtx}{example}}%
+ \file{keycommand.ins}{\from{keycommand.dtx}{install}}%
+ \file{keycommand.sty}{\from{keycommand.dtx}{package}}%
+ \file{keycommand-example.tex}{\from{keycommand.dtx}{example}}%
+}
+
+\generate{%
+ \file{keycommand.drv}{\from{keycommand.dtx}{driver}}%
}
\obeyspaces
@@ -95,17 +99,23 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
%</ignore>
%<*driver>
\edef\thisfile{\jobname}
-\def\thisinfo{an easy way to define commands with optional keys.}
-\def\thisdate{2009/08/26}
-\def\thisversion{2.$\zeta$}
+\def\thisinfo{key-value interface for commands and environments in \LaTeX.}
+\def\thisdate{2010/03/28}
+\def\thisversion{3.0}
\let\loadclass\LoadClass
\def\LoadClass#1{\loadclass[abstracton]{scrartcl}\let\scrmaketitle\maketitle\AtEndOfClass{\let\maketitle\scrmaketitle}}
\documentclass[a4paper,oneside]{ltxdoc}
\usepackage[latin9]{inputenc}
\usepackage[american]{babel}
-\usepackage{etex,holtxdoc,geometry,tocloft,fancyhdr,color,bbding,embedfile,framed,multirow,txfonts}\CodelineNumbered
+\usepackage[T1]{fontenc}
+\usepackage{etex,holtxdoc,geometry,tocloft,graphicx,xspace,fancyhdr,color,bbding,embedfile,framed,multirow,txfonts,makecell,enumitem,arydshln}
+\CodelineNumbered
+\usepackage{keyval}\makeatletter\let\keyval@setkeys\setkeys\makeatother
+\usepackage{xkeyval}\let\xsetkeys\setkeys
+\usepackage{kvsetkeys}
+\usepackage{fancyvrb}
\lastlinefit999
-\geometry{top=2cm,headheight=1cm,headsep=.3cm,bottom=1.4cm,footskip=.5cm,left=4cm,right=2cm}
+\geometry{top=2cm,headheight=1cm,headsep=.3cm,bottom=1.4cm,footskip=.5cm,left=2.5cm,right=1cm}
\hypersetup{%
pdftitle={The keycommand package},
pdfsubject={An e-TeX package for more useful tools for LaTeX package writers},
@@ -121,7 +131,7 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
%</driver>
% \fi
%
-% \CheckSum{770}
+% \CheckSum{0}
%
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
@@ -139,7 +149,7 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
% Grave accent \` Left brace \{ Vertical bar \|
% Right brace \} Tilde \~}
%
-% \DoNotIndex{\begin,\CodelineIndex,\CodelineNumbered,\def,\DisableCrossrefs}
+% \DoNotIndex{\begin,\CodelineIndex,\CodelineNumbered,\def,\DisableCrossrefs,\~,\@ifpackagelater}
% \DoNotIndex{\DocInput,\documentclass,\EnableCrossrefs,\end,\GetFileInfo}
% \DoNotIndex{\NeedsTeXFormat,\OnlyDescription,\RecordChanges,\usepackage}
% \DoNotIndex{\ProvidesClass,\ProvidesPackage,\ProvidesFile,\RequirePackage}
@@ -160,26 +170,37 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
% \DoNotIndex{\",\:,\@empty,\@for,\@gtempa,\@latex@error,\@namedef,\@nameuse,\@tempa,\@testopt,\@width,\\,\m@ne,\makeatletter,\makeatother}
% \DoNotIndex{\maketitle,\parindent,\setbox,\x,\kernel@ifnextchar}
% \DoNotIndex{\KVS@CommaComma,\KVS@CommaSpace,\KVS@EqualsSpace,\KVS@Equals,\KVS@Global,\KVS@SpaceEquals,\KVS@SpaceComma,\KVS@Comma}
-%
+% \DoNotIndex{\DefineShortVerb,\DeleteShortVerb,\UndefineShortVerb,\MakeShortVerb,\endinput}
+% \let\ClearPage\clearpage
% \makeatletter
-% \MakeShortVerb{\+}
-% \catcode`\§\active\def§{\par\nobreak\vskip-\parskip}
-% \def\thispackage{\xpackage{\thisfile}}
-% \def\ThisPackage{\Xpackage{\thisfile}}
+% \MakeShortVerb{\+}\DeleteShortVerb{\|}\DefineShortVerb{\|}
+% \catcode`\§ \active \def§{\@ifnextchar §{\par\nobreak\vskip-2\parskip}{\par\nobreak\vskip-\parskip}}
+% \def\thispackage{\xpackage{\thisfile}\xspace}
+% \def\ThisPackage{\Xpackage{\thisfile}\xspace}
% \def\Xpackage{\@dblarg\X@package}
% \def\X@package[#1]#2{%
% \xpackage{#2\footnote{\noindent\xpackage{#2}: \href{http://www.ctan.org/tex-archive/macros/latex/contrib/#1}{\nolinkurl{CTAN:macros/latex/contrib/#1}}}}}
-
+% \def\Underbrace#1_#2{$\underbrace{\vtop to2ex{}\hbox{#1}}_{\footnotesize\hbox{#2}}$}
%
% \parindent\z@\parskip.4\baselineskip\topsep\parskip\partopsep\z@
% \g@addto@macro\macro@font{\macrocodecolor\let\AltMacroFont\macro@font}
+% \g@addto@macro\@list@extra{\parsep\parskip\topsep\z@\itemsep\z@}
% \def\smex{\leavevmode\hb@xt@2em{\hfil$\longrightarrow$\hfil}}
-% \def\csred#1{\textcolor{red}{\cs{#1}}}
-% \def\CSbf#1{\textbf{\CS{#1}}}
-% \def\csbf#1{\textbf{\cs{#1}}}
-%
-% \fancyhf{}\fancyhead[L]{The \thispackage\ package -- \thisinfo}
-% \fancyfoot[L]{\color[gray]{.35}\scriptsize\thispackage\quad[rev.\thisversion]\quad\copyright\oldstylenums{2009}\,\lower.3ex\hbox{\NibRight}\,Florent Chervet}
+% \renewcommand\#[1]{{\usefont{T1}{pcr}{bx}{n}\char`\##1}}
+% \newcommand\csred[1]{\textcolor{red}{\cs{#1}}}
+% \newcommand\CSbf[1]{\textbf{\CS{#1}}}
+% \newcommand\csbf[1]{\textbf{\cs{#1}}}
+% \renewcommand*\bf{\bfseries}\newcommand\nnn{\normalfont\mdseries\upshape}\newcommand\nbf{\normalfont\bfseries\upshape}
+% \newcommand*\blue{\color{blue}}\newcommand*\red{\color{dr}}\newcommand*\green{\color{green}}\newcommand\rred{\color{red}}
+% \newcommand\rrbf{\color{red}\bfseries}
+% \definecolor{copper}{rgb}{0.67,0.33,0.00} \newcommand\copper{\color{copper}}
+% \definecolor{dg}{rgb}{0.16,0.33,0.00} \newcommand\dg{\color{dg}}
+% \definecolor{db}{rgb}{0,0,0.502} \newcommand\db{\color{db}}
+% \definecolor{dr}{rgb}{0.49,0.00,0.00} \let\dr\red
+% \newcommand\bk{\color{black}}\newcommand\md{\mdseries}
+%
+% \fancyhf{}\fancyhead[L]{The \thispackage package -- \thisinfo}
+% \fancyfoot[L]{\color[gray]{.35}\scriptsize\thispackage\quad[rev.\thisversion]\quad\copyright\oldstylenums{2009-2010}\,\lower.3ex\hbox{\NibRight}\,Florent Chervet}
% \fancyfoot[R]{\oldstylenums{\thepage} / \oldstylenums{\pageref{LastPage}}}
% \pagestyle{fancy}
% \fancypagestyle{plain}{%
@@ -189,14 +210,18 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
%
% \newcommand\macrocodecolor{\color{macrocode}}\definecolor{macrocode}{rgb}{0.18,0.00,0.45}
% \newcommand\reflinkcolor{\color{reflink}}\definecolor{reflink}{rgb}{0.49,0.00,0.00}
-%
+% \font\umrandA=umranda at 20pt
+% \def\@serp{\leavevmode\lower20pt\hbox{\umrandA\char'131}}
+% \def\serp#1{\@serp\hfil #1\hfil\reflectbox{\@serp}}
% \makeatother
%
% \deffootnote{1em}{0pt}{\rlap{\textsuperscript{\thefootnotemark}}\kern1em}
-% \title{\mdseries The{\bfseries\ThisPackage}\kern.6em package}
-% \author{Florent Chervet {\footnotesize\xemail{florent.chervet@free.fr}}}
+%
+% \title{\vskip-18pt\mdseries {\bfseries\ThisPackage}\kern.6em package}
+% \author{\footnotesize\xemail{florent.chervet@free.fr}}
% \date{\thisdate~--~version \thisversion}
% \subtitle{\thisinfo}
+% \subject{\vskip-2cm\serp{The completely redesigned}}
%
% \maketitle
%
@@ -212,91 +237,165 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
% \endgroup\makeatother
%
% \deffootnote{1em}{0pt}{\rlap{\thefootnotemark.}\kern1em}
+% \vskip-12pt
+% \begin{abstract}\parindent0pt\noindent\leftskip=1cm\rightskip\leftskip\lastlinefit0%
%
-% \begin{abstract}\parindent0pt\noindent
+% \thispackage provides an easy way to define commands or environments
+% with optional keys. \csbf{newkeycommand} and its relatives
+% \cs{renewkeycommand}, \csbf{newkeyenvironment}, \linebreak\cs{renewkeyenvironment}
+% and \cs{providekeycommand} are defined in this package.
%
-% \xpackage{keycommand} provides an easy way to define commands or environments
-% with optional keys. It provides \cs{newkeycommand} and its relative
-% \cs{renewkeycommand}, \cs{newkeyenvironment}, \cs{renewkeyenvironment}
-% and \cs{providekeycommand}.
+% Keys are simply defined while defining the command itself in a vary natural way.
+% You can restrict the possible values for the keys by declaring them with a \textbf{type}.
+% Available types for keys are : \textit{boolean}, \textit{enum} and \textit{choice}.^^A Make refs please !!!
%
-% Moreover it is possible to define key-commands using +\def+, +\edef+, +\gdef+ or +\xdef+
-% via the +\keycmd+ prefix.
+% \smallskip
%
-% This package requires and is based on the package \xpackage{kvsetkeys} by Heiko Oberdiek.
-% It is designed to work with \eTeX{} for the code uses the primives +\unexpanded+ and +\protected+.
+% The \thispackage package requires and is based on the package \xpackage{xkeyval} by Hendri Adriaens, and uses
+% the \cs{kv@normalize} macro of \xpackage{kvsetkeys} (Heiko Oberdiek) for robustness, as shown
+% in \ref{kvsetkeys-comparisons}).
%
+% \thispackage is designed to make easier interface for user-defined commands. In particular,
+% \csbf{newkeycommand\string+} permits the use of key-commands in every context.
+%
+% It works with an \eTeX{} distribution of \LaTeX.
% \end{abstract}
%
-% \bigskip
-% \cftbeforesecskip=5pt plus2pt minus4pt
+% \DeleteShortVerb{\+}
+% \cftbeforesecskip=4pt plus2pt minus2pt
+% \cftbeforesubsecskip=0pt plus2pt minus2pt
+% \renewcommand\contentsname{Contents\quad\leaders\vrule height3.4pt depth-3pt\hfill\null\kern0pt\vskip-6pt}
+% ^^A\vskip-.8\baselineskip
% \tableofcontents
%
-% \def\B#1{\texttt{[}\meta{#1}\texttt{]}}
-%
-% \section{Introduction}
-%
-% \subsection{User interface}
-%
-% With \xpackage{keycommand} it becomes very easy to define commands with optional keys.
-% Just say:
-% \begin{tabbing}
-% \qquad\=+\newkeycommand+\=+\CommandWithKeys[kOne=default,+...+][2]{%+\\
-% \>\> definition with +\commandkey{kOne}+ etc. +#1+ and +#2}+
-% \end{tabbing}
+% \clearpage\MakeShortVerb{\+}
%
-% As far as the keys are optional, it is not allowed to have another optional
-% parameter in a key-command.
+% \def\B#1{\texttt{[}\meta{#1}\texttt{]}}
%
-% \goodbreak
-% \xpackage{keycommand} enables us to define key-environments as well, and provides:
-% \begin{center}\begin{tabular}{rll}
-% &+\newkeycommand+ & +\renewkeycommand+ \\
-% &+\newkeyenvironment+ & +\renewkeyenvironment+ \\
-% and:&+\providekeycommand+
-% \end{tabular}\end{center}
+% \section{User Interface}
%
-% Moreover, if you need (or prefer) the syntax of +\def+ (or |\gdef|, |\edef|, |\xdef|)
-% you shall refer to the section \nameref{subsec:keycmd} (in \nameref{Implementation}).
+% \subsection{General syntax}
%
-% \begin{declcs}{newkeycommand}\,\M{control sequence}\,\B{key-value list}\,\B{number of args}\,\M{definition}
+% \begin{declcs}{newkeycommand}%
+% \Underbrace{\textcolor{red}{\textasteriskcentered\string+[short-unexpand]}}_{\makecell[c]{modifiers \\ Optional}}\,%
+% \Underbrace{\M{command}}_{Required}\,%
+% \Underbrace{\B{keys=defaults}\,\B{OptKey}\,\B{<n>}}_{Optional}\,%
+% \Underbrace{\M{definition}}_{Required}
% \end{declcs}
%
-% \xpackage{keycommand} allow \LaTeX{} users to define commands with optional keys in a easy way.
-% Better is a small example than a long talking: let's define a command \cs{Rule} whose
-% +width+, +thickness+ and +raise+ can be specified as keys.
-%
-% With \xpackage{keycommand} we just have to say:§
-% \begin{tabbing}\label{Rule}
-% \,\=+\new+\=+keycommand\Rule[raise=.4ex,width=1em,thick=.4pt][1]{%+\\
+% \cs{newkeycommand} will define \cs{command} as a new key-command!\quad well...
+%
+% Use the \textbf{\dr\textasteriskcentered} form when you do not want it to be a \cs{long} macro (as for \LaTeX{}-\cs{newcommand}).
+%
+% The +[keys=defaults]+ argument define the keys with their default values. It is optional, but a key-command
+% without keys seems to be useless (at least for me...). Keys may be defined as :
+%
+% \newlist{myenum}{enumerate}{1}
+% \setlist[myenum]{label={},topsep=-\parskip,itemsep=-\parskip,parsep=\parskip,after=\vskip-\baselineskip}
+%
+% \renewcommand\theadfont{\tt\bfseries}
+% \noindent\begin{tabular}{|c|>{\db}c|m{8cm}|}\hline
+% \thead{Type} & \thead{exemple} & \thead{value of \cs{commandkey}} \\ \hline
+% general & color=red & \cs{commandkey}\{color\} is `red' and may be anything (text, number, macro...) \\ \hline
+% boolean & bool bold=true & \cs{commandkey}\{bold\} is:
+% \begin{myenum}
+% \item {\tt 0}\quad (for \textit{false})
+% \item {\tt 1}\quad (for \textit{true})
+% \end{myenum} \\ \hline
+% \multirow{2}*{enumerate} & enum position=\{left,centered,right\} & \cs{commandkey}\{position\} is:
+% \begin{myenum}
+% \item `left'\quad by default and can be
+% \item `centered' or
+% \item `right'
+% \end{myenum} \\ \cdashline{2-3}[1pt/2pt]
+% & enum\textasteriskcentered position=\{left,centered,right\} & This is the same, except match is case \textbf{in}sensitive \bottopstrut \\ \hline
+% \multirow{2}*{choice} & choice position=\{left,centered,right\} & \cs{commandkey}\{position\} is:
+% \begin{myenum}
+% \item {\tt 0}\quad (for \textit{left} the default value),
+% \item {\tt 1}\quad (for \textit{centered})
+% \item {\tt 2}\quad (for \textit{right})
+% \end{myenum} \\ \cdashline{2-3}[1pt/2pt]
+% & choice\textasteriskcentered position=\{left,centered,right\} & This is the same, except match is case \textbf{in}sensitive \bottopstrut \\ \hline
+% \end{tabular}
+%
+% The +OptKeys+ argument is used if you wish to capture the +key=value+ pairs that are not specifically defined (more on this in the examples section \ref{sec:examples}).
+%
+% The key-command may have {\tt 0} up to {\tt 9} \textbf{mandatory} arguments : specify the number by +<n>+ ({\tt 0} if omitted).
+%
+% The \textbf{\dr\string+} form expands the \cs{commandkey} before executing the key-command itself, as explain in next section.
+%
+% \subsection{First example :}
+%
+% \begin{tabbing}\label{textrule}
+% \,\=+\new+\=+keycommand\textrule[raise=.4ex,width=3em,thick=.4pt][1]{%+\\
% \>\>+\rule[\commandkey{raise}]{\commandkey{width}}{\commandkey{thick}}+\\
-% \>\>+#1%+\\
+% \>\>\#1 \\
% \>\>+\rule[\commandkey{raise}]{\commandkey{width}}{\commandkey{thick}}}+
% \end{tabbing}
%
% which defines the keys +width+, +thick+ and +raise+ with their default values (if not specified):
-% +1em+, +.4pt+ and +.4ex+. Now \cs{Rule} can be used as follow:
+% +3em+, +.4pt+ and +.4ex+. Now \cs{textrule} can be used as follow:
% \begin{tabbing}
-% \=1:\quad\=+\Rule[width=2em]{hello}+\hskip2cm\=\smex\,\=+width=2em,thick=.4pt,raise=.4ex+\\
-% \>2:\>+\Rule[thick=1pt,width=2em]{hello}+\>\smex\>+width=2em,thick=1pt,raise=.4ex+\\
-% \>3:\>+\Rule{hello}+\quad \>\smex\>+width=1em,thick=.4pt,raise=.4ex+\\
-% \>4:\>+\Rule[thick=2pt,raise=1ex]{hello}+\>\smex\>+width=1em,thick=2pt,raise=1ex+\\
+% \=1:\quad\=+\textrule[width=2em]{hello}+\hskip2.5cm\=\smex\qquad\= \rule[.4ex]{2em}{.4pt}hello\rule[.4ex]{2em}{.4pt} \\
+% \>2:\>+\textrule[thick=5pt,width=2em]{hello}+\>\smex\> \rule[.4ex]{2em}{5pt}hello\rule[.4ex]{2em}{5pt}\\
+% \>3:\>+\textrule{hello}+\quad \>\smex\> \rule[.4ex]{3em}{.4pt}hello\rule[.4ex]{3em}{.4pt}\\
+% \>4:\>+\textrule[thick=2pt,raise=1ex]{hello}+\>\smex\> \rule[1ex]{3em}{2pt}hello\rule[1ex]{3em}{2pt} \\
% \> \textit{et c\ae tera}.
% \end{tabbing}
%
-% They will produce:
-% \begin{tabbing}
-% \=1:\quad\=\rule[.4ex]{2em}{.4pt}hello\rule[.4ex]{2em}{.4pt}\\
-% \>2:\> \rule[.4ex]{2em}{1pt}hello\rule[.4ex]{2em}{1pt}\\
-% \>3:\> \rule[.4ex]{1em}{.4pt}hello\rule[.4ex]{1em}{.4pt}\\
-% \>4:\> \rule[1ex]{1em}{2pt}hello\rule[1ex]{1em}{2pt}
-% \end{tabbing}
+% \clearpage
+%
+% \subsection{Second example : the \string+ form}
+%
+% \DeleteShortVerb{\+}
+% \begin{Verbatim}[gobble=1,commandchars=$(),frame=lines]
+% ($bf\newkeycommand)($dr+[\|])($copper\myfigure)[image,
+% caption,
+% enum placement={H,h,b,t,p},
+% width=\textwidth,
+% label=
+% ][($db OtherKeys)]{%
+% ($dr|)($bf\begin){figure}($dr|)[($red\commandkey){placement}]
+% ($dr|)($bf\includegraphics)($dr|)[width=($red\commandkey){width},($red\commandkey){($db OtherKeys)}]{%
+% ($red\commandkey){image}}%
+% ($dg\ifcommandkey){caption}{($dr|)\caption($dr|){($red\commandkey){caption}}}{}%
+% ($dg\ifcommandkey){label}{($dr|)\label($dr|){($red\commandkey){label}}}{}%
+% ($dr|)($bf\end){figure}($dr|)}
+% \end{Verbatim}
+% \MakeShortVerb{\+}
+%
+% With the {\bf\dr\string+} form of \cs{newkeycommand}, the definition will be expanded (at run time). The optional {\dr\bf+[\|]+} argument
+% means that everything inside {\bf\dr+|+ ... +|+} is protected from expansion.
+%
+% \cs{ifcommandkey}\{\meta{name}\}\{\meta{true}\}\{\meta{false}\}\quad expands \meta{true} if the commandkey \meta{name} is not blank.
+%
+% {\db\cs{Otherkeys}} captures the keys given by the user but not declared: they are simply given back to \cs{includegraphics} here...
+%
+%
+% \subsection{Explanation of the \string+ form}
+% \DeleteShortVerb{\+}
+% The |\commankey{|\meta{name}|}| stuff is expanded at run time using the following scheme:§§
+% \begin{Verbatim}[gobble=1,commandchars=!(),frame=lines]
+% (!bf\newkeycommand)(!copper\keyMacro)[A=\defA,B=\defB,C=\defC,D=\defD][1]{(!dg\begingroup)
+% (!dg\edef)\keyMacro##1{(!dg\endgroup)
+% (!dg\noexpand)\Macro{(!red\getcommandkey){A}}
+% {(!red\getcommandkey){B}}
+% {(!red\getcommandkey){C}}
+% {(!red\getcommandkey){D}}
+% }\keyMacro{#1}}
+% \end{Verbatim}
+% Therefore, the arguments of \cs{Macro} are ready: there is no more \cs{commandkey} stuff, but instead the values of the keys
+% as you give them to the key-command. \cs{getcommandkey}\{A\} is expanded to \cs{defA}.
+%
+% But \cs{defA} is not expanded of course: in the {\bf\dr\string+} form, \cs{commandkey} has the meaning of \cs{getcommandkey}.
%
-% \textsc{Nota bene:} it is also possible to give a key a default value which is the value of another key.
-% For example:§
-% \quad |\newkeycommand\CmdKey[alpha=hello, beta=\commandkey{alpha}]{|...|}|
+% As you can see, the mandatory arguments \#1, \#2 etc. are \textbf{never expanded}: there is no need to protect them inside the special (usually {\dr\bf\textbar}) character.
%
-% When called as: |\CmdKey[alpha=world]|, the key |beta| will then have the same value: |world|.
+%
+% \MakeShortVerb{\+}
+% \clearpage
+%
+% \subsection{key-environments}
%
% \begin{declcs}{newkeyenvironment}\,\M{envir name}\,\B{key-values pairs}\,\B{number of args}\,\M{begin}\,\M{end}
% \end{declcs}
@@ -310,38 +409,83 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
%
% Where $n$ is the number of mandatory other arguments (\emph{ie} without keys), if any.
%
-% A example of a key-environment is left in the file: +keycommand-example.tex+.
+% There is no {\dr\bf\string+} form for key-environments.
%
-% \subsection{Error messages}
%
-% If you use the command +\Rule+ (defined in \ref{Rule}) with a key say: +height+
+% \DefineShortVerb{\+}
+%
+% \section{Messages and more}
+%
+% \subsection{Invalid keys}
+%
+% If you use the command +\textule+ (defined in \ref{textrule}) with a key say: +height+
% that has not been declared at the definition of the key-command, you will get an
% error message like this:
% \begin{quote}\tt
-% There was no key ``height''§
-% in the keycommand \string\Rule!§
-% see the definition of the keycommand.
+% The key-value pairs ``height=...''§
+% cannot be processed for key-command \string\textrule!§
+% See the definition of the keycommand!
% \end{quote}
+% The error is recoverable: the key is ignored.
%
-% However, if you use +\commandkey{height}+ \textbf{in the definition} of +\Rule+ you
-% will not have any error message: +\commandkey{height}+ will just be expanded into +\relax+
-% at +\Rule+ expansion time.
+% If you assign a value to an \textit{enum} or a \textit{choice} key, which is not allowed in the definition,
+% you will get the following message:
+% \begin{quote}\tt
+% The value ``...'' is not allowed in key ...§
+% for key-command \string\command§
+% I'll use the default value ``...'' for this key instead§
+% See the definition of the key-command!
+% \end{quote}
+% The error recoverable: the key is assigned its default value.
+%
+% If you use a \cs{commandkey}\{\meta{name}\} in a key-command where \meta{name} is not defined as a key,
+% you will get the \TeX{} generic error message :§
+% \qquad undefined control sequence : \cs{keycmd->...@name}.
%
-% \edef\restorespaceskip{\spaceskip\the\spaceskip \xspaceskip\the\xspaceskip}
-% \spaceskip=.1em plus.1fil \xspaceskip\spaceskip
-% To be honest, when you redefine a key-command using |\renewkeycommand| or
-% |\renewkeyenvironment| or |\keycmd\def| the keys defined before for the old command are undefined.
-% This way you have the expected error message in all cases.
-% \restorespaceskip
%
-% \subsection{Test if a key is defined}
+% \subsection{Testing keys}
+%
+% \begin{declcs}{ifcommandkey}\,\M{key name}\,\M{commands if key is NOT blank}\,\M{commands if key is blank}
+% \end{declcs}
%
% When you define a key command you may let the default value of a key empty. Then, you may wish to
% expand some commands only if the key has been given by the user (with a non empty value). This can
-% be achieved using the macro |\ifcommandkey|:
+% be achieved using the macro |\ifcommandkey|.
+%
+% \clearpage
+% \subsection{xkeyval, keyval and kvsetkeys comparison}
+%
+% \begin{tabbing}
+% \quad\=\xpackage{xkeyval}: \expandafter\meaning\csname ver@xkeyval.sty\endcsname \\
+% \>\xpackage{keyval}: \expandafter\meaning\csname ver@keyval.sty\endcsname \\
+% \>\xpackage{kvsetkeys}: \expandafter\meaning\csname ver@kvsetkeys.sty\endcsname
+% \end{tabbing}
+%
+% \makeatletter\def\theadfont{\tt\bfseries}
+% \define@key{fam}{key}{\def\result{#1}}
+% \begin{table}[h]\label{kvsetkeys-comparisons}
+% \begin{tabular}{|l|l|>{\color{db}}l|>{\color{dg}}l|}\hline
+% \thead{\bf Example} & \thead{keyval} & \thead{xkeyval} & \thead{\makecell{kvsetkeys\\and\\keycommand}} \\ \hline
+% +\setkeys{fam}{key={{value}}}+
+% & \keyval@setkeys{fam}{key={{value}}}\meaning\result
+% & \xsetkeys{fam}{key={{value}}}\meaning\result
+% & \kvsetkeys{fam}{key={{value}}}\meaning\result \\\hline
+% +\setkeys{fam}{key={{{value}}}}+
+% & \keyval@setkeys{fam}{key={{{value}}}}\meaning\result
+% & \xsetkeys{fam}{key={{{value}}}}\meaning\result
+% & \kvsetkeys{fam}{key={{{value}}}}\meaning\result \\\hline
+% +\setkeys{fam}{key=+\textvisiblespace+{{{value}}}}+
+% & \keyval@setkeys{fam}{key= {{{value}}}}\meaning\result
+% & \xsetkeys{fam}{key= {{{value}}}}\meaning\result
+% & \kvsetkeys{fam}{key= {{{value}}}}\meaning\result \\\hline
+% \end{tabular}
+% \caption{Then it is clear that, at this time, \xpackage{kvsetkeys} has the only correct behaviour...}
+% \end{table}
+%
+% In \thispackage the key-value pairs are first normalized using \xpackage{kvsetkeys}-\cs{kv@normalize}. Then braces are added
+% around the values in order to keep the good behaviour of \xpackage{kvsetkeys} while using \xpackage{xkeyval}.
+% \makeatother
%
-% \begin{declcs}{ifcommandkey}\,\M{key name}\,\M{commands if key is blank}\,\M{commands if key is NOT blank}
-% \end{declcs}
%
%
%
@@ -361,396 +505,510 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
\NeedsTeXFormat{LaTeX2e}% LaTeX 2.09 can't be used (nor non-LaTeX)
[2005/12/01]% LaTeX must be 2005/12/01 or younger (see kvsetkeys.dtx).
\ProvidesPackage{keycommand}
- [2009/07/22 v2.e- an easy way to define commands with optional keys]
+ [2010/03/29 v3.0 - key-value interface for commands and environments in LaTeX]
% \end{macrocode}
%
% \subsection{Requirements}
%
-% The package is based on \xpackage{kvsetkeys}. \xpackage{kvsetkeys} is more
-% reliable than \xpackage{keyval} as far as spaces and bracket (groups) are concerned.
-% Please refer to the \xpackage{kvsetkeys} documentation for more information.
+% The package is based on \xpackage{xkeyval}. However, this \xpackage{xkeyval} is far less reliable
+% than \xpackage{kvsetkeys} as far as spaces and bracket (groups) are concerned, as shown in the section
+% \ref{kvsetkeys-comparisons} of this documentation.
+%
+% Therefore, we also use the macros of \xpackage{kvsetkeys} in order to \textit{normalize} the key=value
+% list before setting the keys. This way, we take advantage of both \xpackage{xkeyval} and \xpackage{kvsetkeys} !
%
% As long as we use \eTeX{} primitives in \xpackage{keycommand} we also load the
% \xpackage{etex} package in order to get an error message if \eTeX{} is not running.
%
+% The \xpackage{etoolbox} package gives some facility to write \xpackage{keycommand} and
+% simplify its code much. \xpackage{etextools} gives a few other facilities.
+%
% \begin{macrocode}
-\RequirePackage{etex,kvsetkeys}
+\def\kcmd@pkg@name{keycommand}
+\RequirePackage{etex,kvsetkeys,xkeyval,etoolbox,etextools}
+% the \setkeys of \xpackage{xkeyval} package :
+\def\kcmd@Xsetkeys{\XKV@testopta{\XKV@testoptc\XKV@setkeys}}% in case \setkeys was overwritten
+\@ifpackagelater{etextools}{2009/08/27}\relax
+ {\PackageError\kcmd@pkg@name{keycommand requires an implementation of\MessageBreak
+ package etextools later than 2009/08/27.\MessageBreak
+ Please update your distribution with a recent version of etextools}%
+ {The keycommand package will not be loaded.}%
+ \expandafter\endinput}
% \end{macrocode}
%
-%
-% \subsection{Syntactical enhancement}
-%
-% We will define a shortcut for +\expandafter\noexpand\csname+...+\endcsname+ all along this package.
% \begin{macrocode}
-\edef\kcmd@AtEnd{\catcode34 \the\catcode34}% "
-\catcode34 4
+\let\kcmd@AtEnd\@empty
+\def\TMP@EnsureCode#1#2{%
+ \edef\kcmd@AtEnd{%
+ \kcmd@AtEnd
+ \catcode#1 \the\catcode#1\relax
+ }%
+ \catcode#1 #2\relax
+}
+\TMP@EnsureCode{32}{10}% space
+\TMP@EnsureCode{61}{12}% = sign
+\TMP@EnsureCode{45}{12}% - sign
+\TMP@EnsureCode{62}{12}% > sign
+\TMP@EnsureCode{46}{12}% . dot
+\TMP@EnsureCode{47}{8}% / slash (etextools)
+\AtEndOfPackage{\kcmd@AtEnd\undef\kcmd@AtEnd}
% \end{macrocode}
%
+% \subsection{Defining (and undefining) command-keys}
%
-% \subsection{Defining keys}
-%
-% \begin{macro}{\kcmd@keydef}
-% To handle the case where the key-command was defined as +\global+, we have to
-% define keys globally too. Therefore, we can't use the +\define@key+ macro of
-% the \xpackage{keyval} package.
+% This macro assign the values to the keys (expansion of \xpackage{xkeyval} \cs{setkeys}
+% on the result of \xpackage{kvsetkeys}-\cs{kv@normalize}):
%
+%\begin{macro}{\kcmd@normalize@setkeys}
% \begin{macrocode}
-\def\kcmd@keydef#1#2#3#4#5{% #1=\global, #2=command, #3=family, #4=key, #5=def
- #1\expandafter\edef\csname kcmd@keys\string#2\endcsname{%
- \csname kcmd@keys\string#2\endcsname,#4}%
- #1\@namedef{KV@#3@#4@default\expandafter}\expandafter{%
- \csname KV@#3@#4\endcsname{#5}}%
- #1\@namedef{KV@#3@#4}##1}
+\newrobustcmd\kcmd@normalize@setkeys[4]{%
+% #1=key-command,
+% #2 = family,
+% #3 = other-key,
+% #4 = key-values pairs
+ \kv@normalize{#4}\edef\kv@list{\csvloop[\kcmd@normalize@braces]\kv@list}%
+ \expandafter\@swaparg\expandafter{\kv@list}{\kcmd@Xsetkeys*{#2}}%
+ \ettl@nbk#3//{\csedef{#2@#3}{\expandonce{\XKV@rm}}}%
+ {\expandafter\ettl@nbk\XKV@rm//%
+ {\PackageError\kcmd@pkg@name{The key-value pairs :\MessageBreak
+ \XKV@rm\MessageBreak
+ cannot be processed for key-command \string#1\MessageBreak
+ See the definition of the key-command!}{}}{}//}//}
+\long\def\kcmd@normalize@braces#1{\kcmd@normalize@br@ces#1==\@nil}
+\long\def\kcmd@normalize@br@ces#1=#2=#3\@nil{\unexpanded{#1={{{#2}}},}}
% \end{macrocode}
-% \end{macro}
+%\end{macro}
%
% \begin{macro}{\kcmd@definekey}
-% In order to define keys, we will use the +\kv@parse+ macro (\xpackage{kvsetkeys}).
-% Therefore, the only requirement is to define the \emph{processor}.
+%
+% \CS{kcmd@definekey} define the keys declared for the key-command.
+% It is used as the \emph{processor} for the \cs{kv@parse} macro of \xpackage{kvsetkeys}.
+%
+% The macro puts the keys just defined into the key list: ``\textit{family}.keylist''.
+%
+% The keys are first checked for their type (bool, enum, enum*, choice or choice*) :
%
% \begin{macrocode}
-\def\kcmd@definekey#1#2#3#4#5{%
- \begingroup\edef\@tempa{\endgroup
- \unexpanded{\kcmd@keydef{#1}{#2}{#3}{#4}{#5}}{\def
- \expandafter\noexpand\csname #3@#4\endcsname{####1}}%
- }\@tempa}
+\def\kcmd@check@typeofkey#1{% expands to
+% 0 if key has no type,
+% 1 if boolean,
+% 2 if enum*,
+% 3 if enum,
+% 4 if choice*,
+% 5 if choice
+ \kcmd@check@typeofkey@bool#1bool //%
+ {\kcmd@check@typeofkey@enumst#1enum* //%
+ {\kcmd@check@typeofkey@enum#1enum //%
+ {\kcmd@check@typeofkey@choicest#1choice* //%
+ {\kcmd@check@typeofkey@choice#1choice //%
+ 05//}4//}3//}2//}1//}
+\def\kcmd@check@typeofkey@bool #1bool #2//{\ettl@nbk#1//}
+\def\kcmd@get@keyname@bool #1bool #2//{#2}
+\def\kcmd@check@typeofkey@enumst #1enum* #2//{\ettl@nbk#1//}
+\def\kcmd@get@keyname@enumst #1enum* #2//{#2}
+\def\kcmd@check@typeofkey@enum #1enum #2//{\ettl@nbk#1//}
+\def\kcmd@get@keyname@enum #1enum #2//{#2}
+\def\kcmd@check@typeofkey@choicest #1choice* #2//{\ettl@nbk#1//}
+\def\kcmd@get@keyname@choicest #1choice* #2//{#2}
+\def\kcmd@check@typeofkey@choice #1choice #2//{\ettl@nbk#1//}
+\def\kcmd@get@keyname@choice #1choice #2//{#2}
+%
+\protected\long\def\kcmd@definekey#1#2#3#4#5{% define the keys using xkeyval macros
+% #1 = keycommand,
+% #2 = \global,
+% #3 = family,
+% #4 = key (before = sign),
+% #5 = default (after = sign)
+ \ifcase\kcmd@check@typeofkey{#4}\relax% standard
+ #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,#4}%
+ \define@cmdkey{#3}[{#3@}]{#4}[{#5}]{}%
+ \or% bool
+ #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,\kcmd@get@keyname@bool#4//}%
+ \kcmd@define@boolkey#1{#3}{\kcmd@get@keyname@bool#4//}{#5}%
+ \or% enum*
+ #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,\kcmd@get@keyname@enumst#4//}%
+ \kcmd@define@choicekey#1*{#3}{\kcmd@get@keyname@enumst#4//}{#5}{\expandonce\val}%
+ \or% enum
+ #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,\kcmd@get@keyname@enum#4//}%
+ \kcmd@define@choicekey#1{}{#3}{\kcmd@get@keyname@enum#4//}{#5}{\expandonce\val}%
+ \or% choice*
+ #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,\kcmd@get@keyname@choicest#4//}%
+ \kcmd@define@choicekey#1*{#3}{\kcmd@get@keyname@choicest#4//}{#5}{\number\nr}%
+ \or% choice
+ #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,\kcmd@get@keyname@choice#4//}%
+ \kcmd@define@choicekey#1{}{#3}{\kcmd@get@keyname@choice#4//}{#5}{\number\nr}%
+ \fi
+ \ifx#2\global\relax
+ #2\csletcs{KV@#3@#4}{KV@#3@#4}% globalize
+ #2\csletcs{KV@#3@#4@default}{KV@#3@#4@default}% globalize default value
+ \fi}
+%
+\long\def\kcmd@firstchoiceof#1,#2\@nil{\unexpanded{#1}}
+%
+\long\def\kcmd@define@choicekey#1#2#3#4#5#6{\begingroup\edef\kcmd@define@choicekey{\endgroup
+ \noexpand\define@choicekey#2+{#3}{#4}
+ [\noexpand\val\noexpand\nr]%
+ {\unexpanded{#5}}% list of allowed values
+ [{\kcmd@firstchoiceof#5,\@nil}]% default value
+ {\csedef{#3@#4}{\unexpanded{#6}}}% define key value if in the allowed list
+ {\kcmd@error@handler\noexpand#1{#3}{#4}{\kcmd@firstchoiceof#5,\@nil}}% error handler
+ }\kcmd@define@choicekey}
+%
+\def\kcmd@define@boolkey#1#2#3#4{\begingroup
+ \ettl@nbk#4//{\def\default{#4}}{\def\default{true}}//%
+ \edef\kcmd@define@boolkey{\endgroup
+ \noexpand\define@choicekey*+{#2}{#3}[\noexpand\val\noexpand\nr]%
+ {false,true}
+ [{\expandonce\default}]%
+ {\csedef{#2@#3}{\noexpand\number\noexpand\nr}}%
+ {\kcmd@error@handler\noexpand#1{#2}{#3}{\expandonce\default}}%
+ }\kcmd@define@boolkey}
+%
+\protected\long\def\kcmd@error@handler#1#2#3#4{%
+% #1 = key-command,
+% #2 = family,
+% #3 = key,
+% #4 = default
+ \PackageError\kcmd@pkg@name{%
+ Value `\val\space' is not allowed in key #3\MessageBreak
+ for key-command \string#1.\MessageBreak
+ I'll use the default value `#4' for this key.\MessageBreak
+ See the definition of the key-command!}{%
+ \csdef{#2@#3}{#4}}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\kcmd@undefinekeys}
% Now in case we redefine a key-command, we would like the old keys (\emph{ie} the keys
% associated to the old definition of the command) to be cleared, undefined.
-% That's the job of +\kcmd@undefinekeys+:
+% That's the job of +\kcmd@undefinekeys+. It uses \cs{csvloop} (in a \cs{edef} in \cmd{kcmd@defcommand}).
%
% \begin{macrocode}
-\def\kcmd@undefinekeys#1#2{%
- \@ifundefined{kcmd@keys\string#2}
- \relax
- {\expandafter\@for\expandafter\kcmp@temp
- \expandafter:\expandafter=\csname kcmd@keys\string#2\endcsname
- \do{#1\expandafter\let
- \csname KV@kcmd@\expandafter\@gobble\string #2@\kcmp@temp @default\endcsname
- \@undefined
- #1\expandafter\let
- \csname KV@kcmd@\expandafter\@gobble\string #2@\kcmp@temp\endcsname
- \@undefined}}%
- #1\@namedef{kcmd@keys\string#2}{\@gobble}}
+\def\kcmd@undefinekeys#1#2{% #1 = global, #2 = family
+ \ifcsundef{#2.keylist}
+ {}
+ {\expandnext{\csvloop[\kcmd@undefinekey{#1}{#2}]}{\csname #2.keylist\endcsname}}%
+ \cslet{#2.keylist}\noexpand\@gobble}
+\def\kcmd@undefinekey#1#2#3{% #1 = global, #2 = family, #3 = key
+ #1\csundef{KV@#2@#3}%
+ #1\csundef{KV@#2@#3@default}%
+}
% \end{macrocode}
% \end{macro}
%
-% \clearpage
-% \subsection{The \csbf{keycmd} prefix} \label{subsec:keycmd}
-%
-% |\keycmd| acts just like a (expandable) prefix for |\def| or |\edef|:
-%
-% The syntax is:§
-% \DeleteShortVerb{\|}\catcode`\|\active\let|\textbar
-% \def\tvs{\textcolor{green}{\textvisiblespace}}
-% \def\cblue{\color{blue}}\def\cred{\color{red}}% \begin{framed}\begin{centering}\begin{tabular}{clll}
-% & \multicolumn{2}{l}{\cs{keycmd}\textcolor{red}{\textasteriskcentered}\tvs} & \textcolor{red}{\textasteriskcentered} optional \\
-% \cblue possibly & & (\csred{long}\tvs|\csred{global}\tvs|\csred{protected}\tvs|\csred{outer}\tvs) & optional (zero or more) \\
-% \cblue in a macro & \multirow{-2}*{\cblue $\Biggl\lbrace$\qquad} & (\cs{def}|\cs{edef}|\cs{gdef}|\cs{xdef}) & required: see below \\
-% & & \textit{control sequence} & required \\
-% & & +[key=value pairs]+ & keys and default values \\
-% & & \textcolor{red}{Parameter string} & optional \\
-% & & \meta{Replacement text} & required
-% \end{tabular}\end{centering}\end{framed}
-
-
-
-%
-% Without the star form, +\long+ is assumed; but it can always be specified as +\long+ \textbf{after}
-% +\keycmd+. Example:§
-% \qquad+\keycmd\gdef\CommandWithKeys[kOne=defOne,kTwo=defTwo]#1#2{+...+}+
-%
-% \begin{macro}{\keycmd}
-% First we have to read the prefixes, if any:
+% \begin{macro}{\kcmd@def}
+% \cs{kcmd@def} checks \cs{@ifdefinable} and cancels definition if needed:
% \begin{macrocode}
-\DeclareRobustCommand\keycmd{\@star@or@long\kcmd@prefix}
+\protected\long\def\kcmd@def#1#2[#3][#4][#5]#6#7{%
+ \@ifdefinable#1{\kcmd@defcommand#1[{#3}][{#4}][{#5}]{#6}{#2}{#7}}}
+% \end{macrocode}
+% \cs{kcmd@defcommand} prepares (expand) the arguments before closing the group opened at the very beginning.
+% Then it proceeds (\cs{kcmd@yargdef} (normal interface) or \cs{kcmd@yargdef} (\string+ modifier))
+% \begin{macrocode}
+\protected\long\def\kcmd@defcommand#1[#2][#3][#4]#5#6#7{%
+ \edef\kcmd@fam{\kcmd@keyfam{#1}}\let\commandkey\relax
+ \edef\kcmd@defcommand{\endgroup
+ \kcmd@undefinekeys{\kcmd@gbl}{\kcmd@fam}% undefines all keys for this keycommand family
+ \kcmd@mount@unexpandchar{\kcmd@fam}{\expandonce\kcmd@unexpandchar}%
+ \unexpanded{\kv@parse{#2,#3}}{\kcmd@definekey\noexpand#1{\kcmd@gbl}{\kcmd@fam}}% defines the keys for this keycommand
+ \csdef{\kcmd@fam.commandkey}####1{\noexpand\csname\kcmd@fam @####1\endcsname}%
+ \csdef{\kcmd@fam.getcommandkey}####1{\unexpanded{\unexpanded\expandafter\expandafter\expandafter}{%
+ \noexpand\csname\kcmd@fam @####1\endcsname}}%
+ \let\commandkey\expandafter\noexpand\csname\kcmd@fam.\kcmd@plus get\fi commandkey\endcsname
+ \kcmd@plus % %% ENDENVIR ??
+ \csdef{\kcmd@fam}{\kcmd@yargedef{\kcmd@gbl}{\kcmd@long}{\noexpandcs\kcmd@fam}{\number#4}{#6}{\csname\kcmd@fam.unexpandchar\endcsname}}%
+ \unless\ifx#6\relax\def#6{\kcmd@yargedef{\kcmd@gbl}{\kcmd@long}{#6}0{\relax}{\csname\kcmd@fam.unexpandchar\endcsname}}\fi
+ \else
+ \csdef{\kcmd@fam}{\kcmd@yargdef{\kcmd@gbl}{\kcmd@long}{\noexpandcs\kcmd@fam}{\number#4}{#6}}%
+ \unless\ifx#6\relax\def#6{\kcmd@yargdef{\kcmd@gbl}{\kcmd@long}{#6}0{\relax}}\fi
+ \fi
+ \kcmd@gbl\protected\edef#1{% entry point %%(?? cas où il n'y a pas de clé => pas besoin de \@testopt\kcmd@init etc ... at run time)
+ \let\noexpand\noexpand\commandkey\noexpand\noexpand\noexpandcs{\kcmd@fam.\kcmd@plus get\fi commandkey}%
+ \noexpand\csvloop[\noexpand\kcmd@resetdefault{\kcmd@fam}]{\noexpandcs{\kcmd@fam.keylist}}%
+ \noexpand\noexpand\noexpand\@testopt{%
+ \kcmd@setkeys\noexpand\noexpand#1{\kcmd@fam}{\kcmd@otherkeys{#3}}}{}}%
+ \noexpandcs\kcmd@fam%
+ }\kcmd@defcommand{#5}{#7}%
+}
+\protected\long\def\kcmd@setkeys#1#2#3[#4]{%
+ \kcmd@normalize@setkeys{#1}{#2}{#3}{#4}\csname#2\endcsname}
+\def\kcmd@resetdefault#1#2{\noexpandcs{KV@#1@#2@default}}
+\long\def\kcmd@otherkeys#1{\ettl@nbk#1//{\kcmd@@therkeys#1=\@nil}{}//}
+\long\def\kcmd@@therkeys#1=#2\@nil{#1}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\kcmd@prefix}
-% This is the prefixes scanner: this macro reads the prefixes one after another (including the +\def+ word)
-% and stores them in +\kcmd@prfx+. We open a group for all declarations will
-% be local until the final definition of +\CommandWithKeys+.
+% \begin{macro}{\kcmd@mount@unexpandchar}
+% This macro defines the macro \cs{"\textit{family.unexpandchar}"}. \CS{"\textit{family.unexpandchar}"} activates the
+% shortcut character for \cs{unexpanded} and defines its meaning.
+% \begin{macrocode}
+\protected\def\kcmd@mount@unexpandchar#1#2{%
+ \ettl@nbk#2//{%
+ \protected\csdef{#1.unexpandchar}{\begingroup
+ \catcode`\~\active \lccode`\~`#2 \lccode`#2 0\relax
+ \lowercase{\def~{\catcode`#2\active
+ \long\def~########1~{\unexpanded{########1}}}%
+ \ettl@aftergroup@def~\endgroup~}}}%
+ {\cslet{#1.unexpandchar}\@empty}//%
+}
+% \end{macrocode}
+% \end{macro}
%
+%----------------------------------------------------------------------------
+% \begin{macro}{\kcmd@yargdef}
+% This is the {\tt argdef} macro for the normal (non \string+) form:
% \begin{macrocode}
-\def\kcmd@prefix{\begingroup
- \let\kcmd@gbl\@empty
- \def\kcmd@prfx{\l@ngrel@x}%
- \futurelet\x\kcmd@@prefix}
-\def\kcmd@@prefix{%
- \let\kcmd@next@addto\kcmd@next@prefix
- \ifx\x\@sptoken \let\next\kcmd@space@prefix
- \else \let\next\kcmd@addto@prfx
- \ifx\x\long
- \else\ifx\x\outer
- \else\ifx\x\protected
- \else\ifx\x\global \def\kcmd@gbl{\global}%
- \else
- \def\kcmd@next@addto{\expandafter\key@cmd\noexpand}%
- \ifx\x\def
- \else\ifx\x\edef
- \else\ifx\x\gdef \def\kcmd@gbl{\global}%
- \else\ifx\x\xdef \def\kcmd@gbl{\global}%
- \else \let\kcmd@next@addto\kcmd@next@prefix
- \ifx\y\x\kcmd@error@prefix
- \else\let\y\x
- \fi
- \let\next\kcmd@expand@prefix
- \fi\fi\fi\fi
- \fi\fi\fi\fi
- \fi\next}
-\def\kcmd@next@prefix{\futurelet\x\kcmd@@prefix}
-\def\kcmd@expand@prefix{\expandafter\kcmd@next@prefix}
-\def\kcmd@addto@prfx#1{\let\y\@undefined
- \expandafter\def\expandafter\kcmd@prfx
- \expandafter{\kcmd@prfx#1}\kcmd@next@addto}
-\expandafter\def\expandafter\kcmd@space@prefix\space{\kcmd@next@prefix}
-\def\kcmd@error@prefix{\@latex@error{A \string\def\space
- (or \string\gdef\space or \string\edef\space or \string\xdef)\MessageBreak
- was expected after \string\keycmd\MessageBreak
- I found a \meaning\x!\MessageBreak
- see keycommand documentation for more information}\@ehd}
+\protected \def \kcmd@yargdef #1#2#3#4#5{\begingroup
+% #1 = global or {}
+% #2 = long or {}
+% #3 = Command
+% #4 = nr of args
+% #5 = endenvir
+ \def \kcmd@yargd@f ##1#4##2##{\afterassignment#5\endgroup
+ #1#2\expandafter\def\expandafter#3\@gobble ##1#4%
+ }\kcmd@yargd@f 0##1##2##3##4##5##6##7##8##9###4%
+}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\key@cmd, \@keycmd}
-% +\key@cmd+ will take the name of the command to be defined as its first argument
-% and checks if there are keys-values placed between brackets just after. Then,
-% +\@keycmd+ will check if the command is definable; if it is not, then the switch
-% +\@tempswa+ is set to false: the definition is processed nevertheless with a basic +\def+,
-% but the group (opened in +\kcmd@prefix+) is closed just after the assignment, canceling
-% everything out.
+% \begin{macro}{\kcmd@yargedef}
+% This is the {\tt argdef} macro for the {\dr\bf\string+} form:
+% \begin{macrocode}
+\protected\def\kcmd@yargedef#1#2#3#4#5#6{\begingroup
+% #1 = global or {}
+% #2 = long or {}
+% #3 = Command
+% #4 = nr of args
+% #5 = endenvir
+% #6 = unexpandchar mounting macro
+ \letcs\kcmd@nargs{kcmd@#4of9}%
+ \long\def\kcmd@yarg@edef##1##2{\afterassignment#5\endgroup
+ #1\edef#3{\begingroup #6%
+ #2\edef\unexpanded{#3##2}{\endgroup\unexpanded{##1}%
+ }\noexpand#3}%
+ }%
+ \protected\def\kcmd@yarg@body{\edef\body{\unexpanded\expandafter\expandafter\expandafter{%
+ \expandafter#3\kcmd@nargs{{####1}}{{####2}}{{####3}}{{####4}}{{####5}}{{####6}}{{####7}}{{####8}}{{####9}}}%
+ }\expandafter\kcmd@yarg@edef\expandafter{\body}}%
+ \def\kcmd@yarged@f##1#4##2##{%
+ \edef\kcmd@yargedef@next{\kcmd@yarg@body{\expandonce{\@gobble ##1#4}}}%
+ \afterassignment\kcmd@yargedef@next
+ \expandafter\def\expandafter#3\@gobble ##1#4%
+ }\kcmd@yarged@f 0##1##2##3##4##5##6##7##8##9###4%
+}
+% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\kcmd@nargs}
+% Filter macros used by \cs{kcmd@yargedef} to get the correct number of arguments:
% \begin{macrocode}
-\def\key@cmd#1{\@testopt{\expandafter\@keycmd\noexpand#1}{}}
-\def\@keycmd#1[#2]{\@tempswafalse\expandafter
- \@rc@ifdefinable\noexpand#1{\@tempswatrue}%
- \if@tempswa
- \let#1=\relax
- \def\next{\kcmd@def#1{#2}}%
- \else \def\next{\afterassignment\endgroup
- \def\kcmd@notdefinable}%
- \fi\next}
+\def\kcmd@XofNINE#1{%
+ \def\kcmd@XofNine##1#1##2##{%
+ \expandafter\csedef{kcmd@#1of9}####1####2####3####4####5####6####7####8####9{%
+ \@gobble ##1#1}%
+ }\kcmd@XofNine 0##1##2##3##4##5##6##7##8##9###1{}%
+}
+\csvloop*[\kcmd@XofNINE]{1,2,3,4,5,6,7,8,9,0}
+\undef\kcmd@XofNine\undef\kcmd@XofNINE
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\kcmd@relaxify}
-% We temporarily assign the value +\relax+ to some commands in order to avoid
-% so many +\noexpand+ during the expanded definition of +\kcmd@def@+:
+% \subsection{new key-commands}
+%
+% \begin{macro}{\newkeycommand}
+% Here are the entry points:
% \begin{macrocode}
-\def\kcmd@relaxify{%
- \let\commandkey\relax
- \let\kvsetkeys\relax
- \let\kv@parse\relax
- \let\@testopt\relax
- \let\kv@set@family@handler\relax
- \let\kcmd@undefinekeys\relax
- \let\kcmd@keyerr\relax
- \let\kcmd@definekey\relax
- \def\"##1"{\expandafter\noexpand\csname ##1\endcsname}}
+\protected\def\newkeycommand{\begingroup
+ \let\kcmd@gbl\@empty\kcmd@modifiers\new@keycommand}
+\protected\def\renewkeycommand{\begingroup
+ \let\kcmd@gbl\@empty\kcmd@modifiers\renew@keycommand}
+\protected\def\providekeycommand{\begingroup
+ \let\kcmd@gbl\@empty\kcmd@modifiers\provide@keycommand}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\kcmd@def}
-% +\kcmd@def+ will define the keys and the command itself:
+% \begin{macro}{\kcmd@modifiers}
+% This macro reads the modifiers for \cs{newkeycommand} (or \cs{newkeyenvironment}) and save them for later use.
+% The scanning of modifiers is performed by \xpackage{etextools}-\cs{futuredef}:
% \begin{macrocode}
-\def\kcmd@def#1#2{% #1=\Command, #2=key-values
- \edef\kcmd@fam{kcmd@\expandafter\@gobble\string#1}%
- \kcmd@relaxify
- \edef\kcmd@def@##1{\endgroup
- \kv@set@family@handler{\kcmd@fam}{\kcmd@keyerr{#1}{####1}{####2}}%
- \kcmd@undefinekeys{\kcmd@gbl}{#1}%
- \kv@parse{##1}{\kcmd@definekey{\kcmd@gbl}{#1}{\kcmd@fam}}%
- \kcmd@gbl\protected\def#1{% entry point
- \def\commandkey########1{\noexpand\csname\kcmd@fam @########1\endcsname}%
- \def\"kcmd\string#1"########1[########2]{%
- \kvsetkeys{\kcmd@fam}{########1,########2}%
- \"\string #1"}%
- \@testopt{\"kcmd\string#1"{##1}}{}}%
- \let\commandkey\relax
- \expandafter\expandafter\expandafter
- \expandafter\expandafter\expandafter
- \expandafter\kcmd@prfx\"\string#1"%
- }\kcmd@def@{#2}}
+\protected\def\kcmd@modifiers#1{%
+ \futuredef[*+]\kcmd@modifiers{% only once inside group
+ \edef\kcmd@long{\expandafter\kcmd@ifstar\kcmd@modifiers*\relax}%
+ \edef\kcmd@plus{\expandafter\kcmd@ifplus\kcmd@modifiers+\relax}%
+ \@testopt{\kcmd@unexpandchar#1}{}}}
+\def\kcmd@ifstar#1*#2\relax{\ettl@nbk#2//{}\long//}
+\def\kcmd@ifplus#1+#2\relax{\ettl@nbk#2//{\noexpand\iftrue}{\noexpand\iffalse}//}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\kcmd@keyerr}
-% +\kcmd@keyerr+ is the default handler for key-commands. It is called
-% whenever the user wants to use a key that was not defined in the key-command:
+%\begin{macro}{\kcmd@unexpandchar}
+% Reads the possible unexpand-char shortcut:
+% \begin{macrocode}
+\def\kcmd@unexpandchar#1[#2]{\def\kcmd@unexpandchar{#2}% only once inside group...
+ \kcmd@plus \ettl@nbk#2//
+ {\def\kcmd@unexpandchar@activate{\catcode`#2 \active}}%
+ {\let\kcmd@unexpandchar@activate\relax}//%
+ \else\ettl@nbk#2//%
+ {\PackageError\kcmd@pkg@name{shortcut option for \string\unexpanded\MessageBreak
+ You can't use a shortcut option for \string\unexpanded\MessageBreak
+ without the \string+ form of \string\newkeycommand!}%
+ {I will ignore this option and proceed.}%
+ \let\kcmd@unexpandchar\@empty}%
+ {}//%
+ \fi#1}
+% \end{macrocode}
+%\end{macro}
%
+% \begin{macro}{\new@keycommand}
+% Reads the key-command name (cs-token):
% \begin{macrocode}
-\def\kcmd@keyerr#1#2#3{%
- \let\wheremsg\@empty
- \ifdefined\trcg@where\trcg@where{#1}\fi
- \@latex@error{There was no key "#2" \MessageBreak
- in the keycommand \string#1!\MessageBreak
- see the definition of the keycommand (or environment)\wheremsg}\@ehd}
+\protected\def\new@keycommand#1{\@testopt{\@newkeycommand#1}{}}
% \end{macrocode}
% \end{macro}
%
-% \subsection{new key-commands}
-%
-% \begin{macro}{\newkeycommand}
-% The +\expandafter+...+\noexpand+ trick is there in case the command to (re-)define
-% had been defined as +\outer+ before...
+%\begin{macro}{\@newkeycommand}
+% Reads the first optional parameter (keys or number of mandatory args):
% \begin{macrocode}
-\DeclareRobustCommand\newkeycommand{\@star@or@long
- {\expandafter\new@keycommand\noexpand}}
-\DeclareRobustCommand\renewkeycommand{\@star@or@long
- {\expandafter\renew@keycommand\noexpand}}
-\DeclareRobustCommand\providekeycommand{\@star@or@long
- {\expandafter\provide@keycommand\noexpand}}
+\protected\def\@newkeycommand#1[#2]{% #2 = key=values or N=mandatory args (also expanded by @newkeyenv)
+ \ifstrnum{#2}%
+ {\@new@key@command#1[][][{#2}]}% no kv, no optkey, number of args
+ {\@testopt{\@new@keycommand#1[{#2}]}0}}% kv, check for optkey/nr of args
% \end{macrocode}
% \end{macro}
%
+%\begin{macro}{\@new@keycommand}
+% Reads the second optional parameter (opt key or number of mandatory args):
+% \begin{macrocode}
+\protected\def\@new@keycommand#1[#2][#3]{%
+ \kcmd@plus \kcmd@unexpandchar@activate \fi% activate unexpand-char before reading definition
+ \ifstrnum{#3}%
+ {\@new@key@command#1[{#2}][][{#3}]}% no optkey
+ {\@testopt{\@new@key@command#1[{#2}][{#3}]}0}}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@new@key@command}
+% Reads the definition of the command (\cs{kcmd@def} handles both the case of commands and environements):
% \begin{macrocode}
-\def\new@keycommand#1{\@testopt{\expandafter\@newkeycommand\noexpand#1}{}}
-\def\@newkeycommand#1[#2]{\begingroup
- \@tempswafalse\expandafter
- \@ifdefinable\noexpand#1{\@tempswatrue}%
- \if@tempswa
- \let#1=\relax
- \let\kcmd@gbl\@empty
- \def\kcmd@prfx##1{\unexpanded{\@testopt{\@argdef{##1}}0}}%
- \def\next{\kcmd@def#1{#2}}%
- \else \def\next{\afterassignment\endgroup
- \def\kcmd@notdefinable}%
- \fi\next}
+\protected\long\def\@new@key@command#1[#2][#3][#4]#5{%
+ \kcmd@def#1\relax[{#2}][{#3}][{#4}]{#5}{}}
% \end{macrocode}
+%\end{macro}
%
+% \begin{macro}{\renew@keycommand}
% \begin{macrocode}
-\def\renew@keycommand#1{\begingroup
+\protected\def\renew@keycommand#1{\begingroup
\escapechar\m@ne\edef\@gtempa{{\string#1}}%
\expandafter\@ifundefined\@gtempa
{\endgroup\@latex@error{\noexpand#1undefined}\@ehc}
\endgroup
\let\@ifdefinable\@rc@ifdefinable
- \expandafter\new@keycommand\noexpand#1}
+ \new@keycommand#1}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\provide@keycommand}
% \begin{macrocode}
-\def\provide@keycommand#1{\begingroup
+\protected\def\provide@keycommand#1{%
\escapechar\m@ne\edef\@gtempa{{\string#1}}%
\expandafter\@ifundefined\@gtempa
- {\endgroup\new@keycommand#1}
- {\endgroup\let\kcmd@notdefinable\noexpand
- \renew@keycommand\kcmd@notdefinable}}
+ {\new@keycommand#1}
+ {\@testopt{\provide@key@command\kcmd@notdefinable}{}}}
+\protected\def\provide@key@command#1[#2]{\@tempswafalse\kcmd@def#1{#2}}
% \end{macrocode}
+% \end{macro}
%
% \subsection{new key-environments}
%
+% \begin{macro}{\newkeyenvironment}
% \begin{macrocode}
-\DeclareRobustCommand\newkeyenvironment{\@star@or@long\new@keyenvironment}
-\DeclareRobustCommand\renewkeyenvironment{\@star@or@long\renew@keyenvironment}
+\protected\def\newkeyenvironment{\begingroup
+ \let\kcmd@gbl\@empty\kcmd@modifiers\new@keyenvironment}
+\protected\def\renewkeyenvironment{\begingroup
+ \let\kcmd@gbl\@empty\kcmd@modifiers\renew@keyenvironment}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\new@keyenvironment}
% \begin{macrocode}
\def\new@keyenvironment#1{\@testopt{\@newkeyenva{#1}}{}}
\def\@newkeyenva#1[#2]{%
- \kernel@ifnextchar [{\@newkeyenvb{#1}[{#2}]}{\@newkeyenv{#1}{[{#2}][0]}}}
-\def\@newkeyenvb#1[#2][#3]{\@newkeyenv{#1}{[{#2}][#3]}}
-\def\@newkeyenv#1#2#3#4{%
- \@ifundefined{#1}%
- {\expandafter\let\csname #1\expandafter\endcsname
- \csname end#1\endcsname}%
- \relax
- \expandafter\@newkeycommand
- \csname #1\endcsname#2{#3}%
- \l@ngrel@x\expandafter\def\csname end#1\endcsname{#4}}
+ \ifstrnum{#2}%
+ {\@newkeyenv{#1}{[][][{#2}]}}
+ {\@testopt{\@newkeyenvb{#1}[{#2}]}{}}}
+\def\@newkeyenvb#1[#2][#3]{%
+ \ifstrnum{#3}%
+ {\@newkeyenv{#1}{[{#2}][][{#3}]}}
+ {\@testopt{\@newkeyenvc{#1}{[{#2}][{#3}]}}0}}
+\def\@newkeyenvc#1#2[#3]{\@newkeyenv{#1}{#2[{#3}]}}
+\long\def\@newkeyenv#1#2{%
+ \kcmd@plus \kcmd@unexpandchar@activate \fi
+ \kcmd@keyenvir@def{#1}{#2}%
+}
+\long\def\kcmd@keyenvir@def#1#2#3#4{%
+ \cslet{end#1}\protected% %%?? et si end#1 est déjà défini et pas #1 (\@ifdefinable ne teste que #1) ??
+ \expandafter\kcmd@def\csname #1\expandafter\endcsname\csname end#1\endcsname#2{#3}{#4}%
+}
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{\renew@keyenvironment}
% \begin{macrocode}
\def\renew@keyenvironment#1{%
\@ifundefined{#1}%
{\@latex@error{Environment #1 undefined}\@ehc
}\relax
- \expandafter\let\csname#1\endcsname\relax
- \expandafter\let\csname\expandafter\string\csname #1\endcsname\endcsname\relax
- \expandafter\let\csname end#1\endcsname\relax
+ \cslet{#1}\relax
\new@keyenvironment{#1}}
% \end{macrocode}
+% \end{macro}
% \iffalse
%<package>
%<package>
% \fi
%
-% \subsection{Test if keys are blank}
+% \subsection{Tests on keys}
%
% First we need some helper macros:
% \begin{macrocode}
\def\kcmd@afterelse#1\else#2\fi{\fi#1}
\def\kcmd@afterfi#1\fi{\fi#1}
+\def\kcmd@keyfam#1{\detokenize{keycmd->}\expandafter\@gobble\string#1}
% \end{macrocode}
%
%
-% \begin{macro}{\expandnext}
-% The following macros comes from the \Xpackage{etextools} package (by F. Chervet):
-% \begin{macrocode}
-\newcommand\kcmd@expandnext[2]{%
- \ifx#1\kcmd@expandnext
- \kcmd@afterelse\expandafter\expandafter\expandafter
- \expandafter\@kcmd@expandnext{#2}{\expandafter\expandafter\expandafter}%
- \else\kcmd@afterfi\expandafter#1\expandafter{#2}%
- \fi}
-\long\def\@kcmd@expandnext#1#2#3{%
- \ifx#1\kcmd@expandnext
- \expandafter\kcmd@afterelse\expandafter\expandafter\expandafter
- \expandafter\@kcmd@expandnext{#3}{\expandafter#2#2}%
- \else
- \expandafter\kcmd@afterfi#2#1#2{#3}%
- \fi}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\kcmd@expandonce}
-% The following macro comes from the \Xpackage{etoolbox} package (by P. Lehmann):
+% \begin{macro}{\ifcommandkey}
% \begin{macrocode}
-\def\kcmd@expandonce#1{\unexpanded\expandafter{#1}}
+\newcommand*\ifcommandkey[1]{\csname @\expandafter\expandafter\expandafter
+ \ettl@nbk\commandkey{#1}//{first}{second}//%
+ oftwo\endcsname}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\kcmd@ifblank}
-% The following macro comes from the \Xpackage[misc/url.sty]{url} package:
-% \begin{macrocode}
-\begingroup\catcode`\:=4\catcode`\&=4
-\gdef\kcmd@ifblank#1{\kcmd@ifblank@#1&&\@secondoftwo\@firstoftwo:}
-\gdef\kcmd@ifblank@#1#2&#3#4#5:{#4}
-\endgroup
-% \end{macrocode}
-% \end{macro}
%
-% \begin{macro}{\ifcommandkey}
+% \begin{macro}{\showcommandkeys}
% \begin{macrocode}
-\newcommand\ifcommandkey[3]{%
- \kcmd@expandnext\kcmd@expandnext\kcmd@expandnext\kcmd@expandnext\kcmd@expandnext
- \kcmd@expandnext\kcmd@expandnext\kcmd@expandnext\kcmd@expandnext\kcmd@expandnext
- \kcmd@expandnext\kcmd@expandnext\kcmd@expandnext\kcmd@ifblank{%
- \kcmd@expandnext\kcmd@expandnext\kcmd@expandonce{\commandkey{#1}}}
- {#3}
- {#2}}
+\newcommand\showcommandkeys[1]{\let\do\showcommandkey\docsvlist{#1}}
+\newcommand\showcommandkey[1]{key \string"#1\string" = %
+ \expandnext\expandnext\expandnext\detokenize{\commandkey{#1}}\par}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
-\kcmd@AtEnd
%</package>
% \end{macrocode}
%
-% \section{Example}
+% \section{Examples}
+% \label{sec:examples}
%
% \begin{macrocode}
%<*example>
\ProvidesFile{keycommand-example}
-\documentclass{article}
+\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage[latin1]{inputenc}
\usepackage[american]{babel}
-\usepackage{keycommand}
-\usepackage{framed}
+\usepackage{keycommand,framed,fancyvrb}
%
\makeatletter
\parindent\z@
@@ -832,12 +1090,15 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
\end{document}
%</example>
% \end{macrocode}
-%
+% \DeleteShortVerb{\+}^^A\UndefineShortVerb{\+}
% \begin{History}
%
-% \begin{Version}{2009/08/26 v2.z}
-% \item
-%
+% \begin{Version}{2010/03/28 v3.0}
+% \item Complete redesign of the implementation. \\
+% \xpackage{keycommand} is now based on some macros of \xpackage{etoolbox}.
+%
+% \item Adding the + prefix and the ability to capture keys that where not defined.
+%
% \end{Version}
%
% \begin{Version}{2009/08/04 v2.e-}
@@ -846,7 +1107,7 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
% \item
% Add History to the documentation file
% \item
-% Modify the prefixes scanner (it is now the same as the one of \Xpackage{ltxnew}).
+% Modify the prefixes scanner (it is now the same as the one of \Xpackage{ltxnew}).\\
% Modify the documentation (\KOMAScript\ classe)
% \end{Version}
%
@@ -859,6 +1120,12 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
%
% \begin{thebibliography}{9}
%
+% \bibitem{xkeyval}
+% Hendri Adriaens:
+% \textit{The \xpackage{xkeyval} package};
+% 2008/08/13 v2.6a;
+% \CTAN{macros/latex/contrib/xkeyval.dtx}
+%
% \bibitem{kvsetkeys}
% Heiko Oberdiek:
% \textit{The \xpackage{kvsetkeys} package};
diff --git a/Master/texmf-dist/source/latex/keycommand/keycommand.ins b/Master/texmf-dist/source/latex/keycommand/keycommand.ins
index 4aa2a36e49f..d6e7afa4861 100644
--- a/Master/texmf-dist/source/latex/keycommand/keycommand.ins
+++ b/Master/texmf-dist/source/latex/keycommand/keycommand.ins
@@ -8,7 +8,7 @@
%%
%% This is a generated file.
%%
-%% keycommand : an easy way to define commands with optional keys [v2.z 2009/08/26]
+%% keycommand : key-value interface for commands and environments in LaTeX [v3.0 2010/03/28]
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either
@@ -22,12 +22,12 @@
%% keycommand-example.tex
%%
%% keycommand : an easy way to define commands with optional keys
-%% Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
+%% Copyright (C) 2009-2010 by Florent Chervet <florent.chervet@free.fr>
%%
\input docstrip.tex
\Msg{************************************************************************}
\Msg{* Installation}
-\Msg{* Package: keycommand 2009/07/22 v1.0 an easy way to define commands with optional keys}
+\Msg{* Package: keycommand 2010/03/28 v3.0 key-value interface for commands and environments in LaTeX}
\Msg{************************************************************************}
\keepsilent
@@ -38,7 +38,7 @@
This is a generated file.
-keycommand : an easy way to define commands with optional keys [v2.z 2009/08/26]
+keycommand : key-value interface for commands and environments in LaTeX [v3.0 2010/03/28]
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either
@@ -52,15 +52,19 @@ and the derived files
keycommand-example.tex
keycommand : an easy way to define commands with optional keys
-Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
+Copyright (C) 2009-2010 by Florent Chervet <florent.chervet@free.fr>
\endpreamble
\let\MetaPrefix\DoubleperCent
\generate{%
- \file{keycommand.ins}{\from{keycommand.dtx}{install}}%
- \file{keycommand.sty}{\from{keycommand.dtx}{package}}%
- \file{keycommand-example.tex}{\from{keycommand.dtx}{example}}%
+ \file{keycommand.ins}{\from{keycommand.dtx}{install}}%
+ \file{keycommand.sty}{\from{keycommand.dtx}{package}}%
+ \file{keycommand-example.tex}{\from{keycommand.dtx}{example}}%
+}
+
+\generate{%
+ \file{keycommand.drv}{\from{keycommand.dtx}{driver}}%
}
\obeyspaces
@@ -79,7 +83,6 @@ Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr>
\Msg{************************************************************************}
\endbatchfile
-
\endinput
%%
%% End of file `keycommand.ins'.