From 82ee4d7b302cb88448593a12e6fd2ae6b0539402 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 27 Apr 2010 00:59:38 +0000 Subject: keycommand update (25apr10) git-svn-id: svn://tug.org/texlive/trunk@18016 c570f23f-e606-0410-a88d-b1316a301751 --- .../doc/latex/keycommand/keycommand-example.pdf | Bin 165101 -> 166465 bytes .../doc/latex/keycommand/keycommand-example.tex | 16 +- .../texmf-dist/doc/latex/keycommand/keycommand.pdf | Bin 318075 -> 329653 bytes .../source/latex/keycommand/keycommand.drv | 8 +- .../source/latex/keycommand/keycommand.dtx | 479 ++++++++++++--------- .../source/latex/keycommand/keycommand.ins | 6 +- .../texmf-dist/tex/latex/keycommand/keycommand.sty | 305 +++++++------ 7 files changed, 478 insertions(+), 336 deletions(-) (limited to 'Master') diff --git a/Master/texmf-dist/doc/latex/keycommand/keycommand-example.pdf b/Master/texmf-dist/doc/latex/keycommand/keycommand-example.pdf index 528da813d02..a042b865da4 100644 Binary files a/Master/texmf-dist/doc/latex/keycommand/keycommand-example.pdf and b/Master/texmf-dist/doc/latex/keycommand/keycommand-example.pdf differ diff --git a/Master/texmf-dist/doc/latex/keycommand/keycommand-example.tex b/Master/texmf-dist/doc/latex/keycommand/keycommand-example.tex index c418a22f86a..66f9ced4e2d 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 : key-value interface for commands and environments in LaTeX [v3.14 2010/04/18] +%% keycommand : key-value interface for commands and environments in LaTeX [v3.141 2010/04/25] %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either @@ -32,18 +32,18 @@ \usepackage{keycommand,framed,fancyvrb} \makeatletter \parindent\z@ -\newkeycommand\Rule[raise=.4ex,width=1em,thick=.4pt][1]{% +\newkeycommand*\Rule[raise=.4ex,width=1em,thick=.4pt][1]{% \rule[\commandkey{raise}]{\commandkey{width}}{\commandkey{thick}}% #1% \rule[\commandkey{raise}]{\commandkey{width}}{\commandkey{thick}}} -\newkeycommand\charleads[sep=1][2]{% +\newkeycommand*\charleads[sep=1][2]{% \ifhmode\else\leavevmode\fi\setbox\@tempboxa\hbox{#2}\@tempdima=1.584\wd\@tempboxa% \cleaders\hb@xt@\commandkey{sep}\@tempdima{\hss\box\@tempboxa\hss}#1% \setbox\@tempboxa\box\voidb@x} -\newcommand\charfill[1][]{\charleads[{#1}]{\hfill\kern\z@}} -\newcommand\charfil[1][]{\charleads[{#1}]{\hfil\kern\z@}} -\newkeyenvironment{dblruled}[first=.4pt,second=.4pt,sep=1pt,left=\z@]{% +\newcommand*\charfill[1][]{\charleads[{#1}]{\hfill\kern\z@}} +\newcommand*\charfil[1][]{\charleads[{#1}]{\hfil\kern\z@}} +\newkeyenvironment*{dblruled}[first=.4pt,second=.4pt,sep=1pt,left=\z@]{% \def\FrameCommand{% \vrule\@width\commandkey{first}% \hskip\commandkey{sep} @@ -81,6 +81,10 @@ \section{Example of a keyenvironment : \texttt{dblruled}} +Key environment \texttt{dblruled } uses \texttt{framed.sty} and therefore it can be used +even if a pagebreak occurs inside the environment: +\medskip + \verb+\begin{dblruled}+\par \verb+ test for dblruled key-environment\par+\par \verb+ test for dblruled key-environment\par+\par diff --git a/Master/texmf-dist/doc/latex/keycommand/keycommand.pdf b/Master/texmf-dist/doc/latex/keycommand/keycommand.pdf index 14e627b040c..3ccfeddde2c 100644 Binary files a/Master/texmf-dist/doc/latex/keycommand/keycommand.pdf and b/Master/texmf-dist/doc/latex/keycommand/keycommand.pdf differ diff --git a/Master/texmf-dist/source/latex/keycommand/keycommand.drv b/Master/texmf-dist/source/latex/keycommand/keycommand.drv index 1ad3fda265e..dfced5eebb2 100644 --- a/Master/texmf-dist/source/latex/keycommand/keycommand.drv +++ b/Master/texmf-dist/source/latex/keycommand/keycommand.drv @@ -8,7 +8,7 @@ %% %% This is a generated file. %% -%% keycommand : key-value interface for commands and environments in LaTeX [v3.14 2010/04/18] +%% keycommand : key-value interface for commands and environments in LaTeX [v3.141 2010/04/25] %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either @@ -26,8 +26,8 @@ %% \edef\thisfile{\jobname} \def\thisinfo{key-value interface for commands and environments in \LaTeX.} -\def\thisdate{2010/04/18} -\def\thisversion{3.14} +\def\thisdate{2010/04/25} +\def\thisversion{3.141} \let\loadclass\LoadClass \def\LoadClass#1{\loadclass[abstracton]{scrartcl}\let\scrmaketitle\maketitle\AtEndOfClass{\let\maketitle\scrmaketitle}} \documentclass[a4paper,oneside]{ltxdoc} @@ -44,7 +44,7 @@ \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}, + pdfsubject={key-value interface for commands and environments in LaTeX.}, pdfauthor={Florent CHERVET}, colorlinks,linkcolor=reflink, pdfstartview={FitH}, diff --git a/Master/texmf-dist/source/latex/keycommand/keycommand.dtx b/Master/texmf-dist/source/latex/keycommand/keycommand.dtx index 9caeb1b4d92..b2007ceb043 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 : key-value interface for commands and environments in LaTeX v3.14 2010/04/18] +% keycommand : key-value interface for commands and environments in LaTeX v3.141 2010/04/25] % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either @@ -37,7 +37,7 @@ \input docstrip.tex \Msg{************************************************************************} \Msg{* Installation} -\Msg{* Package: keycommand 2010/04/18 v3.14 key-value interface for commands and environments in LaTeX} +\Msg{* Package: keycommand 2010/04/25 v3.141 key-value interface for commands and environments in LaTeX} \Msg{************************************************************************} \keepsilent @@ -48,7 +48,7 @@ This is a generated file. -keycommand : key-value interface for commands and environments in LaTeX [v3.14 2010/04/18] +keycommand : key-value interface for commands and environments in LaTeX [v3.141 2010/04/25] This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either @@ -100,8 +100,8 @@ Copyright (C) 2009-2010 by Florent Chervet %<*driver> \edef\thisfile{\jobname} \def\thisinfo{key-value interface for commands and environments in \LaTeX.} -\def\thisdate{2010/04/18} -\def\thisversion{3.14} +\def\thisdate{2010/04/25} +\def\thisversion{3.141} \let\loadclass\LoadClass \def\LoadClass#1{\loadclass[abstracton]{scrartcl}\let\scrmaketitle\maketitle\AtEndOfClass{\let\maketitle\scrmaketitle}} \documentclass[a4paper,oneside]{ltxdoc} @@ -118,7 +118,7 @@ Copyright (C) 2009-2010 by Florent Chervet \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}, + pdfsubject={key-value interface for commands and environments in LaTeX.}, pdfauthor={Florent CHERVET}, colorlinks,linkcolor=reflink, pdfstartview={FitH}, @@ -131,7 +131,7 @@ Copyright (C) 2009-2010 by Florent Chervet % % \fi % -% \CheckSum{960} +% \CheckSum{1053} % % \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 @@ -227,7 +227,8 @@ Copyright (C) 2009-2010 by Florent Chervet % \author{\footnotesize\xemail{florent.chervet@free.fr}} % \date{\thisdate~--~version \thisversion} % \subtitle{\thisinfo} -% \subject{\vskip-2cm\serp{The completely redesigned}} +% ^^A\subject{\vskip-2cm\serp{The completely redesigned}} +% \subject{\vskip-2cm\relax The \textit{free} and \textit{open source}} % % \maketitle % @@ -247,13 +248,19 @@ Copyright (C) 2009-2010 by Florent Chervet % \begin{abstract}\parindent0pt\noindent\leftskip1cm\rightskip\leftskip\lastlinefit0% % % \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. +% with optional keys. +% \smallskip +% +% \csbf{newkeycommand} \cs{renewkeycommand} \cs{providekeycommand} and \csbf{newkeyenvironment},\linebreak +% \cs{renewkeyenvironment} are macros to define such commands and environments with keys. +% +% \thispackage is designed to make easier interface for user-defined commands. In particular, +% \csbf{newkeycommand}\stform+ permits the use of key-commands in every context. +% \medskip % -% Keys are simply defined while defining the command itself in a very natural way. +% Keys are defined with the command itself in a very 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 !!! +% Available types for keys are : \textit{boolean}, \textit{enum} and \textit{choice} (see \ref{subsec:GeneralSyntax}). % % \smallskip % @@ -261,9 +268,6 @@ Copyright (C) 2009-2010 by Florent Chervet % 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} % @@ -280,7 +284,7 @@ Copyright (C) 2009-2010 by Florent Chervet % % \section{User Interface} % -% \subsection{General syntax} +% \subsection{General syntax}\label{subsec:GeneralSyntax} % % \begin{declcs}{newkeycommand}% % \Underbrace{\textcolor{red}{\textasteriskcentered\string+[short-unexpand]}}_{\makecell[c]{modifiers \\ Optional}}\,% @@ -302,29 +306,29 @@ Copyright (C) 2009-2010 by Florent Chervet % \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: +% general & color{\dg=red} & \cs{commandkey}\{{\db color}\} is `{\dg red}' and may be anything (text, number, macro...) \\ \hline +% boolean & {\rred bool} bold{\dg =true} & \cs{commandkey}\{{\db 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 +% \item {\tt 0}\quad (for {\dg false}) +% \item {\tt 1}\quad (for {\dg true}) +% \end{myenum} \\ \hline +% \multirow{2}*{enumerate} & {\rred enum} position{\dg=\{left,centered,right\}} & \cs{commandkey}\{{\db position}\} is: +% \begin{myenum} +% \item `{\dg left}'\quad by default and can be +% \item `{\dg centered}' or +% \item `{\dg right}' +% \end{myenum} \\ \cdashline{2-3}[1pt/2pt] +% & {\rred enum\textasteriskcentered} position{\dg=\{left,centered,right\}} & This is the same, except match is case \textbf{in}sensitive \bottopstrut \\ \hline +% \multirow{2}*{choice} & {\rred choice} position={\dg \{left,centered,right\}} & \cs{commandkey}\{{\db position}\} is: +% \begin{myenum} +% \item {\tt 0}\quad (for {\dg left} the default value), +% \item {\tt 1}\quad (for {\dg centered}) +% \item {\tt 2}\quad (for {\dg right}) +% \end{myenum} \\ \cdashline{2-3}[1pt/2pt] +% & {\rred choice\textasteriskcentered} position={\dg\{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 {\db+OptKey+} 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 ++ ({\tt 0} if omitted). % @@ -339,7 +343,7 @@ Copyright (C) 2009-2010 by Florent Chervet % \>\>\cs{rule}+[+\cs[\red]{commandkey}+{+{\db+raise+}+}]{+\cs[\red]{commandkey}+{+{\db+width+}+}}{+\cs[\red]{commandkey}+{+{\db+thick+}+}}}+ % \end{tabbing} % -% which defines the keys {\db+width+}, {\db+thick+} and {\db+raise+} with their default values (if not specified): +% defines the keys {\db+width+}, {\db+thick+} and {\db+raise+} with their default values (if not specified): % {\db+3em+}, {\db+.4pt+} and {\db+.4ex+}. Now \cs[\copper]{textrule} can be used as follow: % \begin{tabbing} % \=1:\quad\=\cs[\copper]{textrule}+[width=2em]{hello}+\hskip2.5cm\=\smex\qquad\= \rule[.4ex]{2em}{.4pt}hello\rule[.4ex]{2em}{.4pt} \\ @@ -421,10 +425,8 @@ Copyright (C) 2009-2010 by Florent Chervet % Where $n$ is the number of mandatory other arguments (\emph{ie} without keys), if any. % % Key-environments may be defined with the \stform+ form in the same way as \cs{newkeycommand} is used. -% Be aware that each part of the environment: \meta{begin} and \meta{end} are then expanded, and the optional -% {\rred\bf+[\|]+} argument protects from expansion in each of those parts. -% -% +% Be aware that each part of the environment: \meta{begin} and \meta{end} are expanded at run time then, +% and the optional {\rred\bf+[\|]+} argument protects from expansion in each of those parts. % % % \DefineShortVerb{\+} @@ -451,7 +453,7 @@ Copyright (C) 2009-2010 by Florent Chervet % 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. +% The error is 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 :§ @@ -526,33 +528,30 @@ Copyright (C) 2009-2010 by Florent Chervet % % \subsection{Requirements} % -% The package is based on \xpackage{xkeyval}. However, this \xpackage{xkeyval} is far less reliable +% The package is based on \xpackage{xkeyval}. However, \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 +% Therefore, we also use the macros of \xpackage{kvsetkeys} in order to \textit{normalize} the \texttt{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. +% The \xpackage{etoolbox} package gives some facility to write \xpackage{keycommand}. +% +% From version \texttt{3.141} onwards, \thispackage does not load \xpackage{etextools} anymore. % % \begin{macrocode} \def\kcmd@pkg@name{keycommand} -\RequirePackage{etex,kvsetkeys,xkeyval,etoolbox,etextools} +\RequirePackage{etex,kvsetkeys,xkeyval,etoolbox} % \end{macrocode} -% the \cs{setkeys} of \xpackage{xkeyval} package (in case it was overwritten by a +% +% Save the \cs{setkeys} macro of \xpackage{xkeyval} package (in case it was overwritten by a % subsequent load of \xpackage{kvsetkeys} or \xpackage{keyval} for example : % \begin{macrocode} -\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} +\protected\def\kcmd@Xsetkeys{\XKV@sttrue\XKV@plfalse\XKV@testoptc\XKV@setkeys}% in case \setkeys +% was overwritten % \end{macrocode} % Some \cs{catcode} assertions internally used by \thispackage: % \begin{macrocode} @@ -572,6 +571,32 @@ Copyright (C) 2009-2010 by Florent Chervet \TMP@EnsureCode{47}{8}% / slash (etextools) \AtEndOfPackage{\kcmd@AtEnd\undef\kcmd@AtEnd} % \end{macrocode} +% +% \begin{macro}{\kcmd@ifstrdigit}\qquad\qquad +% This macro is used too test the optional arguments of \cs{newkeycommand}, +% in particular, one must know in an argument is a single digit (representing +% the number of mandatory arguments) or anything else (representing the \texttt{key=value} +% list or the ``special'' \texttt{OptKey} key: +% \begin{macrocode} +\iffalse%\ifdefined\pdfmatch% use \pdfmatch if present + \long\def\kcmd@ifstrdigit#1{\csname @\ifnum\pdfmatch + {\detokenize{^[[:space:]]*[[:digit:]][[:space:]]*$}}{\detokenize{#1}}=1 % + first\else second\fi oftwo\endcsname} +\else% use filter, very efficient ! +\def\kcmd@ifstrdigit#1{% + \kcmd@nbk#1//% + {\expandafter\expandafter\expandafter\kcmd@ifstrdigit@i + \expandafter\expandafter\expandafter{\detokenize\expandafter{\number\number0#1}}}% + {\@secondoftwo}//% +} +\def\kcmd@ifstrdigit@i#1{% + \def\kcmd@ifstrdigit@ii##1#1##2##3\kcmd@ifstrdigit@ii{% + \csname @\ifx##20first\else second\fi oftwo\endcsname + }\kcmd@ifstrdigit@ii 00 01 02 03 04 05 06 07 08 09 0#1 \relax\kcmd@ifstrdigit@ii +} +\fi +% \end{macrocode} +% \end{macro} % % \subsection{Defining (and undefining) command-keys} %\begin{macro}{\kcmd@keyfam}\qquad @@ -580,33 +605,41 @@ Copyright (C) 2009-2010 by Florent Chervet \def\kcmd@keyfam#1{\detokenize{keycmd->}\expandafter\@gobble\string#1} % \end{macrocode} % \end{macro} +% \begin{macro}{\kcmd@nbk}\qquad is the optimized \cs{ifnotblank} macro of \xpackage{etoolbox} +% (with \textttbf{/} having a catcode of 8): +% \begin{macrocode} +\def\kcmd@nbk#1#2/#3#4#5//{#4}% +% \end{macrocode} +% \end{macro} % % \begin{macro}{\kcmd@normalize@setkeys}~\par % This macro assigns the values to the keys (expansion of \xpackage{xkeyval}-\cs{setkeys} % on the result of \xpackage{kvsetkeys}-\cs{kv@normalize}). Braces are normalized too so that -% \verb+key= {{{value}}}+ is the same as \verb+key={{{value}}}+ as explained in section \ref{kvsetkeys-comparisons}: +% \verb+key=+\textvisiblespace+{{{value}}}+ is the same as \verb+key={{{value}}}+ as explained in section \ref{kvsetkeys-comparisons}: % \begin{macrocode} \newrobustcmd\kcmd@normalize@setkeys[4]{% % #1 = key-command, % #2 = family, % #3 = other-key, % #4 = key-values pairs - \kv@normalize{#4}\expandafter\let\expandafter\kv@list\expandafter\@empty + \kv@normalize{#4}\toks@{}% \expandafter\kv@parse@normalized\expandafter{\kv@list}{\kcmd@normalize@braces{#2}}% - \expandafter\@swaparg\expandafter{\kv@list,}{\kcmd@Xsetkeys*{#2}}% - \ettl@nbk#3//% undeclared keys are assigned to "OtherKeys" - {\csedef{#2@#3}{\expandonce{\XKV@rm}}}% (if specified, ie not empty) - {\expandafter\ettl@nbk\XKV@rm//% (otherwise a recoverable error is thown) + \edef\kv@list{\kcmd@Xsetkeys{\unexpanded{#2}}{\the\toks@}}\kv@list + \kcmd@nbk#3//% undeclared keys are assigned to "OtherKeys" + {\cslet{#2@#3}\XKV@rm}% (if specified, ie not empty) + {\expandafter\kcmd@nbk\XKV@rm//% (otherwise a recoverable error is thown) {\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!}{}}{}//}//} + See the definition of the key-command!}{}}{}//}//% +} \long\def\kcmd@normalize@braces#1#2#3{% This is kvsetkeys processor for normalizing braces - \edef\kv@list{\expandonce\kv@list,% - #2\if @\detokenize{#3}@\else ={{{\unexpanded{#3}}}}\fi}} + \toks@\expandafter{\the\toks@,#2}% + \ifx @\detokenize{#3}@\else \toks@\expandafter{\the\toks@={{{#3}}}}\fi +} % \end{macrocode} % \end{macro} -% \tracingnone +% % \begin{macro}{\kcmd@definekey}~\par % \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}. @@ -628,15 +661,15 @@ Copyright (C) 2009-2010 by Florent Chervet {\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@check@typeofkey@bool #1bool #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@bool #1bool #2//{#2} -\def\kcmd@check@typeofkey@enumst #1enum* #2//{\ettl@nbk#1//} +\def\kcmd@check@typeofkey@enumst #1enum* #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@enumst #1enum* #2//{#2} -\def\kcmd@check@typeofkey@enum #1enum #2//{\ettl@nbk#1//} +\def\kcmd@check@typeofkey@enum #1enum #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@enum #1enum #2//{#2} -\def\kcmd@check@typeofkey@choicest #1choice* #2//{\ettl@nbk#1//} +\def\kcmd@check@typeofkey@choicest #1choice* #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@choicest #1choice* #2//{#2} -\def\kcmd@check@typeofkey@choice #1choice #2//{\ettl@nbk#1//} +\def\kcmd@check@typeofkey@choice #1choice #2//{\kcmd@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 @@ -667,28 +700,31 @@ Copyright (C) 2009-2010 by Florent Chervet \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} + \fi +} % -\long\def\kcmd@firstchoiceof#1,#2\@nil{\unexpanded{#1}} +\long\def\kcmd@firstchoiceof#1,#2\kcmd@nil{\unexpanded{#1}} % -\long\def\kcmd@define@choicekey#1#2#3#4#5#6{\begingroup\edef\kcmd@define@choicekey{\endgroup +\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 + [{\kcmd@firstchoiceof#5,\kcmd@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} -% + {\kcmd@error@handler\noexpand#1{#3}{#4}{\kcmd@firstchoiceof#5,\kcmd@nil}}% error handler + }\kcmd@define@choicekey +} \def\kcmd@define@boolkey#1#2#3#4{\begingroup - \ettl@nbk#4//{\def\default{#4}}{\def\default{true}}//% + \kcmd@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}]% + [{\unexpanded\expandafter{\default}}]% {\csedef{#2@#3}{\noexpand\number\noexpand\nr}}% - {\kcmd@error@handler\noexpand#1{#2}{#3}{\expandonce\default}}% - }\kcmd@define@boolkey} + {\kcmd@error@handler\noexpand#1{#2}{#3}{\unexpanded\expandafter{\default}}}% + }\kcmd@define@boolkey +} % \protected\long\def\kcmd@error@handler#1#2#3#4{% % #1 = key-command, @@ -707,100 +743,132 @@ Copyright (C) 2009-2010 by Florent Chervet % \begin{macro}{\kcmd@undefinekeys}~\par % 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 \cs{kcmd@undefinekeys}. It uses \cs{csvloop} (in a \cs{edef} in \cs{kcmd@defcommand}). +% That's the job of \cs{kcmd@undefinekeys}. % \begin{macrocode} -\def\kcmd@undefinekeys#1#2{% #1 = global, #2 = family +\protected\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} + {\cslet{#2.keylist}\@gobble} + {\expandafter\expandafter\expandafter\docsvlist + \expandafter\expandafter\expandafter{% + \csname #2.keylist\endcsname}% + \cslet{#2.keylist}\@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} +% +%\begin{macro}{\kcmd@setdefaults}\qquad\qquad +% sets the defaults values for the keys at the very beginning of the keycommand: +% \begin{macrocode} +\def\kcmd@setdefaults#1{% + \ifcsundef{#1.keylist}{} + {\expandafter\expandafter\expandafter\docsvlist + \expandafter\expandafter\expandafter{% + \csname #1.keylist\endcsname}}% +} +% \end{macrocode} +%\end{macro} +% +% % % \begin{macro}{\kcmd@def} % checks \cs{@ifdefinable} and cancels definition if needed: % \begin{macrocode} \protected\long\def\kcmd@def#1#2[#3][#4][#5]#6#7{% - \@ifdefinable#1{\kcmd@defcommand#1[{#3}][{#4}][{#5}]{#6}{#2}{#7}}} + \ifx#1\kcmd@donot@provide\else + \@ifdefinable#1{\kcmd@defcommand#1[{#3}][{#4}][{#5}]{#6}{#2}{#7}}% + \fi +} % \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@yargedef} (when \cs{newkeycommand}\string+ is used)) +% \end{macro} +% +% \begin{macro}{\kcmd@defcommand}\qquad\qquad prepares (expands) the arguments before closing the group opened at the very beginning. +% Then it proceeds (\cs{kcmd@yargdef} (normal interface) or \cs{kcmd@yargedef} (when \cs{newkeycommand}\stform+ is used)) % \begin{macrocode} \protected\long\def\kcmd@defcommand#1[#2][#3][#4]#5#6#7{% \edef\kcmd@fam{\kcmd@keyfam{#1}}\let\commandkey\relax\let\getcommandkey\relax + \let#1\relax \cslet\kcmd@fam\relax + \def\do{\kcmd@undefinekey{\kcmd@gbl}{\kcmd@fam}}% \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}% + \ifx\kcmd@unexpandchar\@empty\else + \kcmd@mount@unexpandchar{\kcmd@fam}{\unexpanded\expandafter{\kcmd@unexpandchar}}% + \fi \unexpanded{\kv@parse{#2,#3}}{\kcmd@definekey\noexpand#1{\kcmd@gbl}{\kcmd@fam}}% defines keys \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\noexpandcs{\kcmd@fam.\kcmd@plus get\fi commandkey}% - % \let\getcommandkey\noexpandcs{\kcmd@fam.getcommandkey}% - \kcmd@plus% \newkeycommand+ - \csdef{\kcmd@fam}{\kcmd@yargedef{\kcmd@gbl}{\kcmd@long}{\noexpandcs\kcmd@fam} - {\number#4}{#6}{\csname\kcmd@fam.unexpandchar\endcsname}}% - \unless\ifx#6\relax% that means we have to define a key-environment - \def#6{\kcmd@yargedef{\kcmd@gbl}{\kcmd@long}{#6}% - 0\relax{\csname\kcmd@fam.unexpandchar\endcsname}}% + \kcmd@ifplus% \newkeycommand+ / \newkeyenvironment+ + \csdef{\kcmd@fam}{% + \kcmd@yargedef{\kcmd@gbl}{\kcmd@long}\csname\kcmd@fam\endcsname + {\number#4}{\noexpand#6}{\csname\kcmd@fam.unexpandchar\endcsname}}% + \ifx#6\@gobble\else \def#6{% that means we have to define a key-environment + \kcmd@yargedef{\kcmd@gbl}{\kcmd@long}{#6}% + 0\relax{\csname\kcmd@fam.unexpandchar\endcsname}}% \fi - \else% \newkeycommand - \csdef{\kcmd@fam}{\kcmd@yargdef{\kcmd@gbl}{\kcmd@long}{\noexpandcs\kcmd@fam} - {\number#4}{#6}}% - \unless\ifx#6\relax% that means we have to define a key-environment - \def#6{\kcmd@yargdef{\kcmd@gbl}{\kcmd@long}{#6}0\relax}% + \else% \newkeycommand / \newkeyenvironment + \csdef{\kcmd@fam}{% + \kcmd@yargdef{\kcmd@gbl}{\kcmd@long}\csname\kcmd@fam\endcsname + {\number#4}{\noexpand#6}}% + \ifx#6\@gobble\else \def#6{% that means we have to define a key-environment + \kcmd@yargdef{\kcmd@gbl}{\kcmd@long}{#6}0\relax}% \fi \fi + \let\commandkey\relax\let\getcommandkey\relax\let#1\relax + \def\noexpand\do####1{\unexpanded{\expandafter\noexpand\csname}KV@\kcmd@fam @####1@default% + \endcsname}% \kcmd@gbl\protected\edef#1{% entry point - \let\noexpand\noexpand\commandkey\noexpand\noexpand\noexpandcs{% - \kcmd@fam.\kcmd@plus get\fi commandkey}% - \let\noexpand\noexpand\getcommandkey\noexpand\noexpand\noexpandcs{% - \kcmd@fam.getcommandkey}% - \noexpand\csvloop[\noexpand\kcmd@resetdefault{\kcmd@fam}]{\noexpandcs{\kcmd@fam.keylist}}% + \let\getcommandkey\unexpanded{\expandafter\noexpand\csname}\kcmd@fam.getcommandkey% + \endcsname + \kcmd@ifplus \let\commandkey\getcommandkey + \else \letcs\commandkey{\kcmd@fam.commandkey}% + \fi + \noexpand\kcmd@setdefaults{\kcmd@fam}% \noexpand\noexpand\noexpand\@testopt{% - \kcmd@setkeys\noexpand\noexpand#1{\kcmd@fam}{\kcmd@otherkeys{#3}}}{}}% - \noexpandcs\kcmd@fam% - }\kcmd@defcommand{#5}{#7}% + \kcmd@setkeys#1{\kcmd@fam}{\kcmd@otherkey{#3}}}{} + }% + \csname\kcmd@fam\endcsname% expand \kcmd@yargedef or \kcmd@yargdef + }\kcmd@defcommand{#5}{#7}% #5 = definition, #7 = definition end-envir } \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} +\long\def\kcmd@otherkey#1{\kcmd@nbk#1//{\kcmd@otherkey@name#1=\kcmd@nil}{}//} +\long\def\kcmd@otherkey@name#1=#2\kcmd@nil{#1} % \end{macrocode} % \end{macro} % % \begin{macro}{\kcmd@mount@unexpandchar}~\par -% This macro defines the macro \cs{"\textit{family.unexpandchar}"}. \CS{"\textit{family.unexpandchar}"} activates the -% shortcut character for \cs{unexpanded} and defines its meaning. +% 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}//% +\protected \def \kcmd@mount@unexpandchar#1#2{% + \protected\csdef{#1.unexpandchar}{\begingroup + \catcode`\~\active \lccode`\~`#2 \lccode`#2 0\relax + \lowercase{% + \expandafter\endgroup\expandafter\def\expandafter~{% + \catcode`#2\active + \long\def~########1~{\unexpanded{########1}}}% + ~}% + }% } % \end{macrocode} % \end{macro} % %---------------------------------------------------------------------------- % \begin{macro}{\kcmd@yargdef}\qquad\qquad -% This is the {\tt argdef} macro for the normal (non \string+) form: +% This is the ``{\tt argdef}'' macro for the normal (non \string+) form: % \begin{macrocode} \protected \def \kcmd@yargdef #1#2#3#4#5{\begingroup % #1 = global or {} % #2 = long or {} % #3 = Command % #4 = nr of args -% #5 = endenvir (or \relax if not an environment) +% #5 = endenvir (or \@gobble if not an environment, or \relax if #3 is 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% @@ -809,16 +877,16 @@ Copyright (C) 2009-2010 by Florent Chervet % \end{macro} % % \begin{macro}{\kcmd@yargedef}\qquad\qquad -% This is the {\tt argdef} macro for the {\dr\bf\string+} form: +% This is the ``{\tt argdef}'' macro for the {\rred\bf\string+} form: % \begin{macrocode} -\protected\def\kcmd@yargedef#1#2#3#4#5#6{\begingroup +\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 (or \relax if not an environment) +% #5 = endenvir (or \@gobble if not an environment, or \relax if #3 is endenvir) % #6 = unexpandchar mounting macro - \letcs\kcmd@nargs{kcmd@#4of9}% + \expandafter\let\expandafter\kcmd@nargs\csname kcmd@#4of9\endcsname \long\def\kcmd@yarg@edef##1##2{\afterassignment#5\endgroup #1\edef#3{\begingroup #6% #2\edef\unexpanded{#3##2}{\endgroup\unexpanded{##1}% @@ -839,14 +907,14 @@ Copyright (C) 2009-2010 by Florent Chervet % \begin{macro}{\kcmd@nargs}\qquad % Filter macros used by \cs{kcmd@yargedef} to get the correct number of arguments: % \begin{macrocode} -\def\kcmd@XofNINE#1{% +\def\do#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 +\docsvlist{1,2,3,4,5,6,7,8,9,0} +\undef\kcmd@XofNine % \end{macrocode} % \end{macro} % @@ -855,43 +923,49 @@ Copyright (C) 2009-2010 by Florent Chervet % \begin{macro}{\newkeycommand}\qquad\qquad % Here are the entry points: % \begin{macrocode} -\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} +\newrobustcmd*\newkeycommand{\begingroup + \let\kcmd@gbl\@empty\kcmd@star@or@long\new@keycommand} +\newrobustcmd*\renewkeycommand{\begingroup + \let\kcmd@gbl\@empty\kcmd@star@or@long\renew@keycommand} +\newrobustcmd*\providekeycommand{\begingroup + \let\kcmd@gbl\@empty\kcmd@star@or@long\provide@keycommand} % \end{macrocode} % \end{macro} % -% \begin{macro}{\kcmd@modifiers}~\par -% 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{macro}{\kcmd@star@or@long}~\par +% This is the adaptation of \LaTeX's \cs{@star@or@long} macro: % \begin{macrocode} -\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@star@or@long#1{\@ifstar + {\let\kcmd@long\@empty\kcmd@plus#1} + {\def\kcmd@long{\long}\kcmd@plus#1}} +\def\kcmd@@ifplus#1{\@ifnextchar +{\@firstoftwo{#1}}}% same as LaTeX's \@ifstar +\def\kcmd@plus#1{\kcmd@@ifplus + {\def\kcmd@ifplus{\iftrue}\kcmd@testopt#1} + {\def\kcmd@ifplus{\iffalse}\kcmd@testopt#1}} +\def\kcmd@testopt#1{\@testopt{\kcmd@unexpandchar#1}{}} % \end{macrocode} % \end{macro} % %\begin{macro}{\kcmd@unexpandchar}\qquad\qquad\quad % 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}% - {}//% +\def\kcmd@unexpandchar#1[#2]{% + \kcmd@ifplus + \kcmd@nbk#2// + {\def\kcmd@unexpandchar{#2}% only once inside group... + \def\kcmd@unexpandchar@activate{\catcode`#2 \active}% + }{% + \let\kcmd@unexpandchar\@empty + \let\kcmd@unexpandchar@activate\relax + }//% + \else \let\kcmd@unexpandchar\@empty + \kcmd@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.}% + }% + {}//% \fi#1} % \end{macrocode} %\end{macro} @@ -899,16 +973,16 @@ Copyright (C) 2009-2010 by Florent Chervet % \begin{macro}{\new@keycommand}\qquad\qquad % Reads the key-command name (cs-token): % \begin{macrocode} -\protected\def\new@keycommand#1{\@testopt{\@newkeycommand#1}{}} +\def\new@keycommand#1{\@testopt{\@newkeycommand#1}0} % \end{macrocode} % \end{macro} % %\begin{macro}{\@newkeycommand}\qquad\qquad % Reads the first optional parameter (keys or number of mandatory args): % \begin{macrocode} -\protected\def\@newkeycommand#1[#2]{% #2 = key=values or N=mandatory args - \kcmd@plus \kcmd@unexpandchar@activate \fi% activates unexpand-char before reading definition - \ifstrnum{#2}% +\long\def\@newkeycommand#1[#2]{% #2 = key=values or N=mandatory args + \kcmd@ifplus \kcmd@unexpandchar@activate \fi% activates unexpand-char before reading definition + \kcmd@ifstrdigit{#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} @@ -917,8 +991,8 @@ Copyright (C) 2009-2010 by Florent Chervet %\begin{macro}{\@new@keycommand}\qquad\qquad % Reads the second optional parameter (opt key or number of mandatory args): % \begin{macrocode} -\protected\def\@new@keycommand#1[#2][#3]{% - \ifstrnum{#3}% +\long\def\@new@keycommand#1[#2][#3]{% + \kcmd@ifstrdigit{#3}% {\@new@key@command#1[{#2}][][{#3}]}% no optkey {\@testopt{\@new@key@command#1[{#2}][{#3}]}0}} % \end{macrocode} @@ -928,31 +1002,34 @@ Copyright (C) 2009-2010 by Florent Chervet % Reads the definition of the command (\cs{kcmd@def} handles both cases of commands and environements). % The so called "unexpand-char shortcut" has been activated before reading command definition: % \begin{macrocode} -\protected\long\def\@new@key@command#1[#2][#3][#4]#5{% - \kcmd@def#1\relax[{#2}][{#3}][{#4}]{#5}{}} +\long\def\@new@key@command#1[#2][#3][#4]#5{% + \kcmd@def#1\@gobble[{#2}][{#3}][{#4}]{#5}{}} % \end{macrocode} %\end{macro} % % \begin{macro}{\renew@keycommand} % \begin{macrocode} -\protected\def\renew@keycommand#1{\begingroup +\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 - \new@keycommand#1} + \new@keycommand#1% +} % \end{macrocode} % \end{macro} % % \begin{macro}{\provide@keycommand} % \begin{macrocode} -\protected\def\provide@keycommand#1{% +\def\provide@keycommand#1{\begingroup \escapechar\m@ne\edef\@gtempa{{\string#1}}% \expandafter\@ifundefined\@gtempa - {\new@keycommand#1} - {\@testopt{\provide@key@command\kcmd@notdefinable}{}}} -\protected\def\provide@key@command#1[#2]{\@tempswafalse\kcmd@def#1{#2}} + {\endgroup\new@keycommand#1} + {\endgroup\def\kcmd@donot@provide{\renew@keycommand\kcmd@donot@provide + }\kcmd@donot@provide}% +} +\let\kcmd@donot@provide\@empty% it must not be undefined % \end{macrocode} % \end{macro} % @@ -960,31 +1037,31 @@ Copyright (C) 2009-2010 by Florent Chervet % % \begin{macro}{\newkeyenvironment} % \begin{macrocode} -\protected\def\newkeyenvironment{\begingroup - \let\kcmd@gbl\@empty\kcmd@modifiers\new@keyenvironment} -\protected\def\renewkeyenvironment{\begingroup - \let\kcmd@gbl\@empty\kcmd@modifiers\renew@keyenvironment} +\newrobustcmd*\newkeyenvironment{\begingroup + \let\kcmd@gbl\@empty\kcmd@star@or@long\new@keyenvironment} +\newrobustcmd\renewkeyenvironment{\begingroup + \let\kcmd@gbl\@empty\kcmd@star@or@long\renew@keyenvironment} % \end{macrocode} % \end{macro} % % \begin{macro}{\new@keyenvironment} % \begin{macrocode} \def\new@keyenvironment#1{\@testopt{\@newkeyenva{#1}}{}} -\def\@newkeyenva#1[#2]{% - \ifstrnum{#2}% +\long\def\@newkeyenva#1[#2]{% + \kcmd@ifstrdigit{#2}% {\@newkeyenv{#1}{[][][{#2}]}} {\@testopt{\@newkeyenvb{#1}[{#2}]}{}}} -\def\@newkeyenvb#1[#2][#3]{% - \ifstrnum{#3}% +\long\def\@newkeyenvb#1[#2][#3]{% + \kcmd@ifstrdigit{#3}% {\@newkeyenv{#1}{[{#2}][][{#3}]}} {\@testopt{\@newkeyenvc{#1}{[{#2}][{#3}]}}0}} -\def\@newkeyenvc#1#2[#3]{\@newkeyenv{#1}{#2[{#3}]}} +\long\def\@newkeyenvc#1#2[#3]{\@newkeyenv{#1}{#2[{#3}]}} \long\def\@newkeyenv#1#2{% - \kcmd@plus \kcmd@unexpandchar@activate \fi + \kcmd@ifplus \kcmd@unexpandchar@activate \fi \kcmd@keyenvir@def{#1}{#2}% } \long\def\kcmd@keyenvir@def#1#2#3#4{% - \cslet{end#1}\protected + \expandafter\let\csname end#1\endcsname\relax \expandafter\kcmd@def\csname #1\expandafter\endcsname\csname end#1\endcsname#2{#3}{#4}% } % \end{macrocode} @@ -1012,7 +1089,7 @@ Copyright (C) 2009-2010 by Florent Chervet % is not blank: % \begin{macrocode} \newcommand*\ifcommandkey[1]{\csname @\expandafter\expandafter\expandafter - \ettl@nbk\commandkey{#1}//{first}{second}//% + \kcmd@nbk\commandkey{#1}//{first}{second}//% oftwo\endcsname} % \end{macrocode} % \end{macro} @@ -1020,11 +1097,12 @@ Copyright (C) 2009-2010 by Florent Chervet % % \begin{macro}{\showcommandkeys}\qquad\qquad are helper macros essentially for debuging purpose... % \begin{macrocode} -\newcommand\showcommandkeys[1]{\let\do\showcommandkey\docsvlist{#1}} -\newcommand\showcommandkey[1]{key \string"#1\string" = % - \expandnext\expandnext\expandnext\detokenize{\commandkey{#1}}\par} +\newrobustcmd*\showcommandkeys[1]{\let\do\showcommandkey\docsvlist{#1}} +\newrobustcmd*\showcommandkey[1]{key \string"#1\string" = % + \detokenize\expandafter\expandafter\expandafter{\commandkey{#1}}\par} % \end{macrocode} % \end{macro} +% % % \begin{macrocode} % @@ -1044,19 +1122,19 @@ Copyright (C) 2009-2010 by Florent Chervet % \makeatletter \parindent\z@ -\newkeycommand\Rule[raise=.4ex,width=1em,thick=.4pt][1]{% +\newkeycommand*\Rule[raise=.4ex,width=1em,thick=.4pt][1]{% \rule[\commandkey{raise}]{\commandkey{width}}{\commandkey{thick}}% #1% \rule[\commandkey{raise}]{\commandkey{width}}{\commandkey{thick}}} -\newkeycommand\charleads[sep=1][2]{% +\newkeycommand*\charleads[sep=1][2]{% \ifhmode\else\leavevmode\fi\setbox\@tempboxa\hbox{#2}\@tempdima=1.584\wd\@tempboxa% \cleaders\hb@xt@\commandkey{sep}\@tempdima{\hss\box\@tempboxa\hss}#1% \setbox\@tempboxa\box\voidb@x} -\newcommand\charfill[1][]{\charleads[{#1}]{\hfill\kern\z@}} -\newcommand\charfil[1][]{\charleads[{#1}]{\hfil\kern\z@}} +\newcommand*\charfill[1][]{\charleads[{#1}]{\hfill\kern\z@}} +\newcommand*\charfil[1][]{\charleads[{#1}]{\hfil\kern\z@}} % -\newkeyenvironment{dblruled}[first=.4pt,second=.4pt,sep=1pt,left=\z@]{% +\newkeyenvironment*{dblruled}[first=.4pt,second=.4pt,sep=1pt,left=\z@]{% \def\FrameCommand{% \vrule\@width\commandkey{first}% \hskip\commandkey{sep} @@ -1096,6 +1174,10 @@ Copyright (C) 2009-2010 by Florent Chervet \section{Example of a keyenvironment : \texttt{dblruled}} +Key environment \texttt{dblruled } uses \texttt{framed.sty} and therefore it can be used +even if a pagebreak occurs inside the environment: +\medskip + \verb+\begin{dblruled}+\par \verb+ test for dblruled key-environment\par+\par \verb+ test for dblruled key-environment\par+\par @@ -1126,6 +1208,13 @@ Copyright (C) 2009-2010 by Florent Chervet % \end{macrocode} % \DeleteShortVerb{\+}^^A\UndefineShortVerb{\+} % \begin{History} +% +% \begin{Version}{2010/04/25 v3.141} +% \item No new feature but a real improvement in optimization. \\ +% In particular, \thispackage does not load \xpackage{etextools} anymore. \\ +% \item Bug fix for \cs{providekeycommand}. +% +% \end{Version} % % \begin{Version}{2010/04/18 v3.14} % \item Correction of bug in the normalization process. \\ diff --git a/Master/texmf-dist/source/latex/keycommand/keycommand.ins b/Master/texmf-dist/source/latex/keycommand/keycommand.ins index 07f1cd3e334..7d63becf333 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 : key-value interface for commands and environments in LaTeX [v3.14 2010/04/18] +%% keycommand : key-value interface for commands and environments in LaTeX [v3.141 2010/04/25] %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either @@ -27,7 +27,7 @@ \input docstrip.tex \Msg{************************************************************************} \Msg{* Installation} -\Msg{* Package: keycommand 2010/04/18 v3.14 key-value interface for commands and environments in LaTeX} +\Msg{* Package: keycommand 2010/04/25 v3.141 key-value interface for commands and environments in LaTeX} \Msg{************************************************************************} \keepsilent @@ -38,7 +38,7 @@ This is a generated file. -keycommand : key-value interface for commands and environments in LaTeX [v3.14 2010/04/18] +keycommand : key-value interface for commands and environments in LaTeX [v3.141 2010/04/25] This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either diff --git a/Master/texmf-dist/tex/latex/keycommand/keycommand.sty b/Master/texmf-dist/tex/latex/keycommand/keycommand.sty index 9f79ac612aa..3bf7e801bd1 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 : key-value interface for commands and environments in LaTeX [v3.14 2010/04/18] +%% keycommand : key-value interface for commands and environments in LaTeX [v3.141 2010/04/25] %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either @@ -29,14 +29,8 @@ \ProvidesPackage{keycommand} [2010/04/18 v3.14 - 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} +\RequirePackage{etex,kvsetkeys,xkeyval,etoolbox} +\protected\def\kcmd@Xsetkeys{\XKV@sttrue\XKV@plfalse\XKV@testoptc\XKV@setkeys}% in case \setkeys \let\kcmd@AtEnd\@empty \def\TMP@EnsureCode#1#2{% \edef\kcmd@AtEnd{% @@ -52,21 +46,41 @@ \TMP@EnsureCode{46}{12}% . dot \TMP@EnsureCode{47}{8}% / slash (etextools) \AtEndOfPackage{\kcmd@AtEnd\undef\kcmd@AtEnd} +\iffalse%\ifdefined\pdfmatch% use \pdfmatch if present + \long\def\kcmd@ifstrdigit#1{\csname @\ifnum\pdfmatch + {\detokenize{^[[:space:]]*[[:digit:]][[:space:]]*$}}{\detokenize{#1}}=1 % + first\else second\fi oftwo\endcsname} +\else% use filter, very efficient ! +\def\kcmd@ifstrdigit#1{% + \kcmd@nbk#1//% + {\expandafter\expandafter\expandafter\kcmd@ifstrdigit@i + \expandafter\expandafter\expandafter{\detokenize\expandafter{\number\number0#1}}}% + {\@secondoftwo}//% +} +\def\kcmd@ifstrdigit@i#1{% + \def\kcmd@ifstrdigit@ii##1#1##2##3\kcmd@ifstrdigit@ii{% + \csname @\ifx##20first\else second\fi oftwo\endcsname + }\kcmd@ifstrdigit@ii 00 01 02 03 04 05 06 07 08 09 0#1 \relax\kcmd@ifstrdigit@ii +} +\fi \def\kcmd@keyfam#1{\detokenize{keycmd->}\expandafter\@gobble\string#1} +\def\kcmd@nbk#1#2/#3#4#5//{#4}% \newrobustcmd\kcmd@normalize@setkeys[4]{% - \kv@normalize{#4}\expandafter\let\expandafter\kv@list\expandafter\@empty + \kv@normalize{#4}\toks@{}% \expandafter\kv@parse@normalized\expandafter{\kv@list}{\kcmd@normalize@braces{#2}}% - \expandafter\@swaparg\expandafter{\kv@list,}{\kcmd@Xsetkeys*{#2}}% - \ettl@nbk#3//% undeclared keys are assigned to "OtherKeys" - {\csedef{#2@#3}{\expandonce{\XKV@rm}}}% (if specified, ie not empty) - {\expandafter\ettl@nbk\XKV@rm//% (otherwise a recoverable error is thown) + \edef\kv@list{\kcmd@Xsetkeys{\unexpanded{#2}}{\the\toks@}}\kv@list + \kcmd@nbk#3//% undeclared keys are assigned to "OtherKeys" + {\cslet{#2@#3}\XKV@rm}% (if specified, ie not empty) + {\expandafter\kcmd@nbk\XKV@rm//% (otherwise a recoverable error is thown) {\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!}{}}{}//}//} + See the definition of the key-command!}{}}{}//}//% +} \long\def\kcmd@normalize@braces#1#2#3{% This is kvsetkeys processor for normalizing braces - \edef\kv@list{\expandonce\kv@list,% - #2\if @\detokenize{#3}@\else ={{{\unexpanded{#3}}}}\fi}} + \toks@\expandafter{\the\toks@,#2}% + \ifx @\detokenize{#3}@\else \toks@\expandafter{\the\toks@={{{#3}}}}\fi +} \def\kcmd@check@typeofkey#1{% expands to \kcmd@check@typeofkey@bool#1bool //% {\kcmd@check@typeofkey@enumst#1enum* //% @@ -74,15 +88,15 @@ {\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@check@typeofkey@bool #1bool #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@bool #1bool #2//{#2} -\def\kcmd@check@typeofkey@enumst #1enum* #2//{\ettl@nbk#1//} +\def\kcmd@check@typeofkey@enumst #1enum* #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@enumst #1enum* #2//{#2} -\def\kcmd@check@typeofkey@enum #1enum #2//{\ettl@nbk#1//} +\def\kcmd@check@typeofkey@enum #1enum #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@enum #1enum #2//{#2} -\def\kcmd@check@typeofkey@choicest #1choice* #2//{\ettl@nbk#1//} +\def\kcmd@check@typeofkey@choicest #1choice* #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@choicest #1choice* #2//{#2} -\def\kcmd@check@typeofkey@choice #1choice #2//{\ettl@nbk#1//} +\def\kcmd@check@typeofkey@choice #1choice #2//{\kcmd@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 @@ -107,25 +121,29 @@ \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 + \fi +} +\long\def\kcmd@firstchoiceof#1,#2\kcmd@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 + [{\kcmd@firstchoiceof#5,\kcmd@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} + {\kcmd@error@handler\noexpand#1{#3}{#4}{\kcmd@firstchoiceof#5,\kcmd@nil}}% error handler + }\kcmd@define@choicekey +} \def\kcmd@define@boolkey#1#2#3#4{\begingroup - \ettl@nbk#4//{\def\default{#4}}{\def\default{true}}//% + \kcmd@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}]% + [{\unexpanded\expandafter{\default}}]% {\csedef{#2@#3}{\noexpand\number\noexpand\nr}}% - {\kcmd@error@handler\noexpand#1{#2}{#3}{\expandonce\default}}% - }\kcmd@define@boolkey} + {\kcmd@error@handler\noexpand#1{#2}{#3}{\unexpanded\expandafter{\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 @@ -133,75 +151,96 @@ 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 +\protected\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} + {\cslet{#2.keylist}\@gobble} + {\expandafter\expandafter\expandafter\docsvlist + \expandafter\expandafter\expandafter{% + \csname #2.keylist\endcsname}% + \cslet{#2.keylist}\@gobble}% +} \def\kcmd@undefinekey#1#2#3{% #1 = global, #2 = family, #3 = key #1\csundef{KV@#2@#3}% #1\csundef{KV@#2@#3@default}% } +\def\kcmd@setdefaults#1{% + \ifcsundef{#1.keylist}{} + {\expandafter\expandafter\expandafter\docsvlist + \expandafter\expandafter\expandafter{% + \csname #1.keylist\endcsname}}% +} \protected\long\def\kcmd@def#1#2[#3][#4][#5]#6#7{% - \@ifdefinable#1{\kcmd@defcommand#1[{#3}][{#4}][{#5}]{#6}{#2}{#7}}} + \ifx#1\kcmd@donot@provide\else + \@ifdefinable#1{\kcmd@defcommand#1[{#3}][{#4}][{#5}]{#6}{#2}{#7}}% + \fi +} \protected\long\def\kcmd@defcommand#1[#2][#3][#4]#5#6#7{% \edef\kcmd@fam{\kcmd@keyfam{#1}}\let\commandkey\relax\let\getcommandkey\relax + \let#1\relax \cslet\kcmd@fam\relax + \def\do{\kcmd@undefinekey{\kcmd@gbl}{\kcmd@fam}}% \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}% + \ifx\kcmd@unexpandchar\@empty\else + \kcmd@mount@unexpandchar{\kcmd@fam}{\unexpanded\expandafter{\kcmd@unexpandchar}}% + \fi \unexpanded{\kv@parse{#2,#3}}{\kcmd@definekey\noexpand#1{\kcmd@gbl}{\kcmd@fam}}% defines keys \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\noexpandcs{\kcmd@fam.\kcmd@plus get\fi commandkey}% - % \let\getcommandkey\noexpandcs{\kcmd@fam.getcommandkey}% - \kcmd@plus% \newkeycommand+ - \csdef{\kcmd@fam}{\kcmd@yargedef{\kcmd@gbl}{\kcmd@long}{\noexpandcs\kcmd@fam} - {\number#4}{#6}{\csname\kcmd@fam.unexpandchar\endcsname}}% - \unless\ifx#6\relax% that means we have to define a key-environment - \def#6{\kcmd@yargedef{\kcmd@gbl}{\kcmd@long}{#6}% - 0\relax{\csname\kcmd@fam.unexpandchar\endcsname}}% + \kcmd@ifplus% \newkeycommand+ / \newkeyenvironment+ + \csdef{\kcmd@fam}{% + \kcmd@yargedef{\kcmd@gbl}{\kcmd@long}\csname\kcmd@fam\endcsname + {\number#4}{\noexpand#6}{\csname\kcmd@fam.unexpandchar\endcsname}}% + \ifx#6\@gobble\else \def#6{% that means we have to define a key-environment + \kcmd@yargedef{\kcmd@gbl}{\kcmd@long}{#6}% + 0\relax{\csname\kcmd@fam.unexpandchar\endcsname}}% \fi - \else% \newkeycommand - \csdef{\kcmd@fam}{\kcmd@yargdef{\kcmd@gbl}{\kcmd@long}{\noexpandcs\kcmd@fam} - {\number#4}{#6}}% - \unless\ifx#6\relax% that means we have to define a key-environment - \def#6{\kcmd@yargdef{\kcmd@gbl}{\kcmd@long}{#6}0\relax}% + \else% \newkeycommand / \newkeyenvironment + \csdef{\kcmd@fam}{% + \kcmd@yargdef{\kcmd@gbl}{\kcmd@long}\csname\kcmd@fam\endcsname + {\number#4}{\noexpand#6}}% + \ifx#6\@gobble\else \def#6{% that means we have to define a key-environment + \kcmd@yargdef{\kcmd@gbl}{\kcmd@long}{#6}0\relax}% \fi \fi + \let\commandkey\relax\let\getcommandkey\relax\let#1\relax + \def\noexpand\do####1{\unexpanded{\expandafter\noexpand\csname}KV@\kcmd@fam @####1@default% + \endcsname}% \kcmd@gbl\protected\edef#1{% entry point - \let\noexpand\noexpand\commandkey\noexpand\noexpand\noexpandcs{% - \kcmd@fam.\kcmd@plus get\fi commandkey}% - \let\noexpand\noexpand\getcommandkey\noexpand\noexpand\noexpandcs{% - \kcmd@fam.getcommandkey}% - \noexpand\csvloop[\noexpand\kcmd@resetdefault{\kcmd@fam}]{\noexpandcs{\kcmd@fam.keylist}}% + \let\getcommandkey\unexpanded{\expandafter\noexpand\csname}\kcmd@fam.getcommandkey% + \endcsname + \kcmd@ifplus \let\commandkey\getcommandkey + \else \letcs\commandkey{\kcmd@fam.commandkey}% + \fi + \noexpand\kcmd@setdefaults{\kcmd@fam}% \noexpand\noexpand\noexpand\@testopt{% - \kcmd@setkeys\noexpand\noexpand#1{\kcmd@fam}{\kcmd@otherkeys{#3}}}{}}% - \noexpandcs\kcmd@fam% - }\kcmd@defcommand{#5}{#7}% + \kcmd@setkeys#1{\kcmd@fam}{\kcmd@otherkey{#3}}}{} + }% + \csname\kcmd@fam\endcsname% expand \kcmd@yargedef or \kcmd@yargdef + }\kcmd@defcommand{#5}{#7}% #5 = definition, #7 = definition end-envir } \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}//% +\long\def\kcmd@otherkey#1{\kcmd@nbk#1//{\kcmd@otherkey@name#1=\kcmd@nil}{}//} +\long\def\kcmd@otherkey@name#1=#2\kcmd@nil{#1} +\protected \def \kcmd@mount@unexpandchar#1#2{% + \protected\csdef{#1.unexpandchar}{\begingroup + \catcode`\~\active \lccode`\~`#2 \lccode`#2 0\relax + \lowercase{% + \expandafter\endgroup\expandafter\def\expandafter~{% + \catcode`#2\active + \long\def~########1~{\unexpanded{########1}}}% + ~}% + }% } \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}% +\protected \def \kcmd@yargedef#1#2#3#4#5#6{\begingroup + \expandafter\let\expandafter\kcmd@nargs\csname kcmd@#4of9\endcsname \long\def\kcmd@yarg@edef##1##2{\afterassignment#5\endgroup #1\edef#3{\begingroup #6% #2\edef\unexpanded{#3##2}{\endgroup\unexpanded{##1}% @@ -216,84 +255,94 @@ \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\do#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}% - {}//% +\docsvlist{1,2,3,4,5,6,7,8,9,0} +\undef\kcmd@XofNine +\newrobustcmd*\newkeycommand{\begingroup + \let\kcmd@gbl\@empty\kcmd@star@or@long\new@keycommand} +\newrobustcmd*\renewkeycommand{\begingroup + \let\kcmd@gbl\@empty\kcmd@star@or@long\renew@keycommand} +\newrobustcmd*\providekeycommand{\begingroup + \let\kcmd@gbl\@empty\kcmd@star@or@long\provide@keycommand} +\def\kcmd@star@or@long#1{\@ifstar + {\let\kcmd@long\@empty\kcmd@plus#1} + {\def\kcmd@long{\long}\kcmd@plus#1}} +\def\kcmd@@ifplus#1{\@ifnextchar +{\@firstoftwo{#1}}}% same as LaTeX's \@ifstar +\def\kcmd@plus#1{\kcmd@@ifplus + {\def\kcmd@ifplus{\iftrue}\kcmd@testopt#1} + {\def\kcmd@ifplus{\iffalse}\kcmd@testopt#1}} +\def\kcmd@testopt#1{\@testopt{\kcmd@unexpandchar#1}{}} +\def\kcmd@unexpandchar#1[#2]{% + \kcmd@ifplus + \kcmd@nbk#2// + {\def\kcmd@unexpandchar{#2}% only once inside group... + \def\kcmd@unexpandchar@activate{\catcode`#2 \active}% + }{% + \let\kcmd@unexpandchar\@empty + \let\kcmd@unexpandchar@activate\relax + }//% + \else \let\kcmd@unexpandchar\@empty + \kcmd@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.}% + }% + {}//% \fi#1} -\protected\def\new@keycommand#1{\@testopt{\@newkeycommand#1}{}} -\protected\def\@newkeycommand#1[#2]{% #2 = key=values or N=mandatory args - \kcmd@plus \kcmd@unexpandchar@activate \fi% activates unexpand-char before reading definition - \ifstrnum{#2}% +\def\new@keycommand#1{\@testopt{\@newkeycommand#1}0} +\long\def\@newkeycommand#1[#2]{% #2 = key=values or N=mandatory args + \kcmd@ifplus \kcmd@unexpandchar@activate \fi% activates unexpand-char before reading definition + \kcmd@ifstrdigit{#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]{% - \ifstrnum{#3}% +\long\def\@new@keycommand#1[#2][#3]{% + \kcmd@ifstrdigit{#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 +\long\def\@new@key@command#1[#2][#3][#4]#5{% + \kcmd@def#1\@gobble[{#2}][{#3}][{#4}]{#5}{}} +\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 - \new@keycommand#1} -\protected\def\provide@keycommand#1{% + \new@keycommand#1% +} +\def\provide@keycommand#1{\begingroup \escapechar\m@ne\edef\@gtempa{{\string#1}}% \expandafter\@ifundefined\@gtempa - {\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} + {\endgroup\new@keycommand#1} + {\endgroup\def\kcmd@donot@provide{\renew@keycommand\kcmd@donot@provide + }\kcmd@donot@provide}% +} +\let\kcmd@donot@provide\@empty% it must not be undefined +\newrobustcmd*\newkeyenvironment{\begingroup + \let\kcmd@gbl\@empty\kcmd@star@or@long\new@keyenvironment} +\newrobustcmd\renewkeyenvironment{\begingroup + \let\kcmd@gbl\@empty\kcmd@star@or@long\renew@keyenvironment} \def\new@keyenvironment#1{\@testopt{\@newkeyenva{#1}}{}} -\def\@newkeyenva#1[#2]{% - \ifstrnum{#2}% +\long\def\@newkeyenva#1[#2]{% + \kcmd@ifstrdigit{#2}% {\@newkeyenv{#1}{[][][{#2}]}} {\@testopt{\@newkeyenvb{#1}[{#2}]}{}}} -\def\@newkeyenvb#1[#2][#3]{% - \ifstrnum{#3}% +\long\def\@newkeyenvb#1[#2][#3]{% + \kcmd@ifstrdigit{#3}% {\@newkeyenv{#1}{[{#2}][][{#3}]}} {\@testopt{\@newkeyenvc{#1}{[{#2}][{#3}]}}0}} -\def\@newkeyenvc#1#2[#3]{\@newkeyenv{#1}{#2[{#3}]}} +\long\def\@newkeyenvc#1#2[#3]{\@newkeyenv{#1}{#2[{#3}]}} \long\def\@newkeyenv#1#2{% - \kcmd@plus \kcmd@unexpandchar@activate \fi + \kcmd@ifplus \kcmd@unexpandchar@activate \fi \kcmd@keyenvir@def{#1}{#2}% } \long\def\kcmd@keyenvir@def#1#2#3#4{% - \cslet{end#1}\protected + \expandafter\let\csname end#1\endcsname\relax \expandafter\kcmd@def\csname #1\expandafter\endcsname\csname end#1\endcsname#2{#3}{#4}% } \def\renew@keyenvironment#1{% @@ -305,11 +354,11 @@ \newcommand*\ifcommandkey[1]{\csname @\expandafter\expandafter\expandafter - \ettl@nbk\commandkey{#1}//{first}{second}//% + \kcmd@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} +\newrobustcmd*\showcommandkeys[1]{\let\do\showcommandkey\docsvlist{#1}} +\newrobustcmd*\showcommandkey[1]{key \string"#1\string" = % + \detokenize\expandafter\expandafter\expandafter{\commandkey{#1}}\par} \endinput %% %% End of file `keycommand.sty'. -- cgit v1.2.3