diff options
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/latex/keycommand/README | 15 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/keycommand/keycommand-example.pdf | bin | 135984 -> 147252 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/keycommand/keycommand-example.tex | 10 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/keycommand/keycommand.pdf | bin | 220135 -> 191903 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/keycommand/keycommand.drv | 59 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/keycommand/keycommand.dtx | 1013 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/keycommand/keycommand.ins | 21 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/keycommand/keycommand.sty | 429 |
8 files changed, 982 insertions, 565 deletions
diff --git a/Master/texmf-dist/doc/latex/keycommand/README b/Master/texmf-dist/doc/latex/keycommand/README index aaa4981ba4b..b41e8b81b01 100644 --- a/Master/texmf-dist/doc/latex/keycommand/README +++ b/Master/texmf-dist/doc/latex/keycommand/README @@ -18,7 +18,20 @@ % % Documentation: % (pdf)latex keycommand.dtx - +% +% ----------------------------------------------------------------- +% Typical example: +% +% \newkeycommand+[\|]\myFigure[ +% caption={\textcolor{red}{<no caption given>}, +% placement=h}][OtherKeys][1]{% +% |\begin{figure}|[\commandkey{placement}] +% |\includegraphics|[\commandkey{OtherKeys}]{#1} +% |\caption|{\commandkey{caption}}} +% Usage : +% +% \myFigure[caption=small image,page=12,viewport=20 50 136 95,clip]{image.pdf} +% ----------------------------------------------------------------- diff --git a/Master/texmf-dist/doc/latex/keycommand/keycommand-example.pdf b/Master/texmf-dist/doc/latex/keycommand/keycommand-example.pdf Binary files differindex 61fc8d38dcb..894a4b77550 100644 --- a/Master/texmf-dist/doc/latex/keycommand/keycommand-example.pdf +++ b/Master/texmf-dist/doc/latex/keycommand/keycommand-example.pdf diff --git a/Master/texmf-dist/doc/latex/keycommand/keycommand-example.tex b/Master/texmf-dist/doc/latex/keycommand/keycommand-example.tex index c508e28c21a..8e07e07c262 100644 --- a/Master/texmf-dist/doc/latex/keycommand/keycommand-example.tex +++ b/Master/texmf-dist/doc/latex/keycommand/keycommand-example.tex @@ -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,16 +22,14 @@ %% 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> %% - \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@ \newkeycommand\Rule[raise=.4ex,width=1em,thick=.4pt][1]{% diff --git a/Master/texmf-dist/doc/latex/keycommand/keycommand.pdf b/Master/texmf-dist/doc/latex/keycommand/keycommand.pdf Binary files differindex 83be1a41c1d..76eb62bc544 100644 --- a/Master/texmf-dist/doc/latex/keycommand/keycommand.pdf +++ b/Master/texmf-dist/doc/latex/keycommand/keycommand.pdf 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#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'. diff --git a/Master/texmf-dist/tex/latex/keycommand/keycommand.sty b/Master/texmf-dist/tex/latex/keycommand/keycommand.sty index 738ed1f69a5..fbb8b0f007d 100644 --- a/Master/texmf-dist/tex/latex/keycommand/keycommand.sty +++ b/Master/texmf-dist/tex/latex/keycommand/keycommand.sty @@ -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,204 +22,281 @@ %% 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> %% - \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] -\RequirePackage{etex,kvsetkeys} -\edef\kcmd@AtEnd{\catcode34 \the\catcode34}% " -\catcode34 4 -\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} -\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@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}} - -\DeclareRobustCommand\keycmd{\@star@or@long\kcmd@prefix} -\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}% + [2010/03/29 v3.0 - key-value interface for commands and environments in LaTeX] +\def\kcmd@pkg@name{keycommand} +\RequirePackage{etex,kvsetkeys,xkeyval,etoolbox,etextools} +\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} +\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} +\newrobustcmd\kcmd@normalize@setkeys[4]{% + \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}}},}} +\def\kcmd@check@typeofkey#1{% expands to + \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 + \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{% + \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}}} +\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}% +} +\protected\long\def\kcmd@def#1#2[#3][#4][#5]#6#7{% + \@ifdefinable#1{\kcmd@defcommand#1[{#3}][{#4}][{#5}]{#6}{#2}{#7}}} +\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 - \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} -\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@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}} -\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}} -\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} -\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}} -\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} -\def\renew@keycommand#1{\begingroup + \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} +\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}//% +} +\protected \def \kcmd@yargdef #1#2#3#4#5{\begingroup + \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% +} +\protected\def\kcmd@yargedef#1#2#3#4#5#6{\begingroup + \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% +} +\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 +\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} +\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}//} +\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} +\protected\def\new@keycommand#1{\@testopt{\@newkeycommand#1}{}} +\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 +\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}} +\protected\long\def\@new@key@command#1[#2][#3][#4]#5{% + \kcmd@def#1\relax[{#2}][{#3}][{#4}]{#5}{}} +\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} -\def\provide@keycommand#1{\begingroup + \new@keycommand#1} +\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}} -\DeclareRobustCommand\newkeyenvironment{\@star@or@long\new@keyenvironment} -\DeclareRobustCommand\renewkeyenvironment{\@star@or@long\renew@keyenvironment} + {\new@keycommand#1} + {\@testopt{\provide@key@command\kcmd@notdefinable}{}}} +\protected\def\provide@key@command#1[#2]{\@tempswafalse\kcmd@def#1{#2}} +\protected\def\newkeyenvironment{\begingroup + \let\kcmd@gbl\@empty\kcmd@modifiers\new@keyenvironment} +\protected\def\renewkeyenvironment{\begingroup + \let\kcmd@gbl\@empty\kcmd@modifiers\renew@keyenvironment} \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}% +} \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}} \def\kcmd@afterelse#1\else#2\fi{\fi#1} \def\kcmd@afterfi#1\fi{\fi#1} -\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} -\def\kcmd@expandonce#1{\unexpanded\expandafter{#1}} -\begingroup\catcode`\:=4\catcode`\&=4 -\gdef\kcmd@ifblank#1{\kcmd@ifblank@#1&&\@secondoftwo\@firstoftwo:} -\gdef\kcmd@ifblank@#1#2#4#5:{#4} -\endgroup -\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}} -\kcmd@AtEnd +\def\kcmd@keyfam#1{\detokenize{keycmd->}\expandafter\@gobble\string#1} +\newcommand*\ifcommandkey[1]{\csname @\expandafter\expandafter\expandafter + \ettl@nbk\commandkey{#1}//{first}{second}//% + oftwo\endcsname} +\newcommand\showcommandkeys[1]{\let\do\showcommandkey\docsvlist{#1}} +\newcommand\showcommandkey[1]{key \string"#1\string" = % + \expandnext\expandnext\expandnext\detokenize{\commandkey{#1}}\par} \endinput %% %% End of file `keycommand.sty'. |