% \iffalse meta-comment % keycommand : an easy way to define commands with keys % % 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 % % Unpacking: % (a) If keycommand.ins is present: % etex keycommand.ins % (b) Without keycommand.ins: % etex keycommand.dtx % (c) If you insist on using LaTeX % latex \let\install=y\input{keycommand.dtx} % (quote the arguments according to the demands of your shell) % % Documentation: % (pdf)latex keycommand.dtx % Copyright (C) 2009 by Florent Chervet %<*ignore> \begingroup \def\x{LaTeX2e}% \expandafter\endgroup \ifcase 0\ifx\install y1\fi\expandafter \ifx\csname processbatchFile\endcsname\relax\else1\fi \ifx\fmtname\x\else 1\fi\relax \else\csname fi\endcsname % %<*install> \input docstrip.tex \Msg{************************************************************************} \Msg{* Installation} \Msg{* Package: keycommand 2009/07/22 v1.0 an easy way to define commands with keys} \Msg{************************************************************************} \keepsilent \askforoverwritefalse \let\MetaPrefix\relax \preamble This is a generated file. keycommand : an easy way to define commands with keys 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 keys Copyright (C) 2009 by Florent Chervet \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}}% } \obeyspaces \Msg{************************************************************************} \Msg{*} \Msg{* To finish the installation you have to move the following} \Msg{* file into a directory searched by TeX:} \Msg{*} \Msg{* keycommand.sty} \Msg{*} \Msg{* To produce the documentation run the file `keycommand.dtx'} \Msg{* through LaTeX.} \Msg{*} \Msg{* Happy TeXing!} \Msg{*} \Msg{************************************************************************} \endbatchfile % %<*ignore> \fi % %<*driver> \documentclass[a4paper,oneside]{ltxdoc} \usepackage[latin9]{inputenc} \usepackage[american]{babel} \usepackage{etex,holtxdoc,geometry,tocloft,fancyhdr,color,bbding}\CodelineNumbered \lastlinefit999 \font\ding=dingbat scaled 800 \geometry{top=2cm,headheight=1cm,headsep=.3cm,bottom=2cm,left=5cm,right=3cm} \fancyhf{}\fancyhead[L]{The \xpackage{keycommand} package -- easy way to define commands with keys} \fancyfoot[L]{\color[gray]{.35}\scriptsize\xpackage{keycommand}\quad\copyright\oldstylenums{2009}\,\lower.3ex\hbox{\NibRight}\,Florent Chervet} \fancyfoot[R]{\oldstylenums{\thepage} / \oldstylenums{\pageref{LastPage}}} \pagestyle{fancy} \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} \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} \begin{document} \DocInput{keycommand.dtx} \end{document} % % \fi % % \CheckSum{673} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % \DoNotIndex{\begin,\CodelineIndex,\CodelineNumbered,\def,\DisableCrossrefs} % \DoNotIndex{\DocInput,\documentclass,\EnableCrossrefs,\end,\GetFileInfo} % \DoNotIndex{\NeedsTeXFormat,\OnlyDescription,\RecordChanges,\usepackage} % \DoNotIndex{\ProvidesClass,\ProvidesPackage,\ProvidesFile,\RequirePackage} % \DoNotIndex{\filename,\fileversion,\filedate,\let} % \DoNotIndex{\@listctr,\@nameuse,\csname,\else,\endcsname,\expandafter} % \DoNotIndex{\gdef,\global,\if,\item,\newcommand,\nobibliography} % \DoNotIndex{\par,\providecommand,\relax,\renewcommand,\renewenvironment} % \DoNotIndex{\stepcounter,\usecounter,\nocite,\fi} % \DoNotIndex{\@fileswfalse,\@gobble,\@ifstar,\@unexpandable@protect} % \DoNotIndex{\AtBeginDocument,\AtEndDocument,\begingroup,\endgroup} % \DoNotIndex{\frenchspacing,\MessageBreak,\newif,\PackageWarningNoLine} % \DoNotIndex{\protect,\string,\xdef,\ifx,\texttt,\@biblabel,\bibitem} % \DoNotIndex{\z@,\wd,\wheremsg,\vrule,\voidb@x,\verb,\bibitem} % \DoNotIndex{\FrameCommand,\MakeFramed,\FrameRestore,\hskip,\hfil,\hfill,\hsize,\hspace,\hss,\hbox,\hb@xt@,\endMakeFramed,\escapechar} % \DoNotIndex{\do,\date,\if@tempswa,\@tempdima,\@tempboxa,\@tempswatrue,\@tempswafalse,\ifdefined,\ifhmode,\ifmmode,\cr} % \DoNotIndex{\box,\author,\advance,\multiply,\Command,\outer,\next,\leavevmode,\kern,\title,\toks@,\trcg@where,\tt} % \DoNotIndex{\the,\width,\star,\space,\section,\subsection,\textasteriskcentered,\textwidth} % \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} % % \title{The \xpackage{keycommand}\kern6pt package} % \author{Florent Chervet \xemail{florent.chervet@free.fr}} % \date{July 22, 2009} % % \MakeShortVerb{\+} % % \catcode`\§\active\def§{\par\nobreak\vskip-\parskip} % \makeatletter % \parindent\z@\parskip.4\baselineskip\topsep\parskip\partopsep\z@ % \g@addto@macro\macro@font{\macrocodecolor\let\AltMacroFont\macro@font} % \def\smex{\leavevmode\hb@xt@2em{\hfil$\longrightarrow$\hfil}} % \makeatother % % \maketitle % % \begin{abstract}\parindent0pt\noindent % % \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}. % % Moreover it is possible to define key-commands using +\def+, +\edef+, +\gdef+ or +\xdef+ % via the +\keycmd+ prefix. % % 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+. % % \end{abstract}\vskip-\baselineskip % \makeatletter\let\@thefnmark\@empty % \@footnotetext{This documentation is produced with the +DocStrip+ utility. % \begin{tabbing} % \qquad\=\smex\=To get the documentation, \= run (thrice):\quad\= \texttt{pdflatex keycommand.dtx} \\ % \>\smex\>To get the package, \> run:\> \texttt{etex keycommand.dtx} % \end{tabbing}}\makeatother % % \cftbeforesecskip=5pt plus2pt minus4pt % \tableofcontents % \tracingnone % % \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} % % As far as the keys are optional, it is not allowed to have another optional % parameter in a key-command. % % \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} % 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}). % % \begin{declcs}{newkeycommand}\,\M{control sequence}\,\B{key-value list}\,\B{number of args}\,\M{definition} % \end{declcs} % % \xpackage{keycommand} allow \LaTeX{} users to define commands with key 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]{%+\\ % \>\>+\rule[\commandkey{raise}]{\commandkey{width}}{\commandkey{thick}}+\\ % \>\>+#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: % \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+\\ % \> \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} % % \begin{declcs}{newkeyenvironment}\,\M{envir name}\,\B{key-values pairs}\,\B{number of args}\,\M{begin}\,\M{end} % \end{declcs} % % In the same way, you may define environments with optional keys as follow:§ % \begin{tabbing} % \qquad\=+\newkeyenvironment+\=+{EnvirWithKeys}[kOne=+default value,...+][n]+\\ % \>\>+{+ commands at begin +EnvirWithKeys }+ \\ % \>\>+{+ commands at end +EnvirWithKeys }+ % \end{tabbing} % % 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+. % % \enlargethispage{\baselineskip} % \subsection{Error messages} % % If you use the command +\Rule+ (defined in \ref{Rule}) 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. % \end{quote} % % 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. % % 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. % % \StopEventually{ % } % % \begin{center}\vskip6pt$\star$\hskip4em\lower12pt\hbox{$\star$}\hskip4em$\star$\vadjust{\vskip12pt}\end{center} % % \section{Implementation} \label{Implementation} % % \subsection{Identification} % % This package is intended to use with \LaTeX{} so we don't check if it is loaded twice. % % \begin{macrocode} %<*package> \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 an easy way to define commands with keys] % \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. % % 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. % % \begin{macrocode} \RequirePackage{etex,kvsetkeys} % \end{macrocode} % % \iffalse % \subsection{Syntactical enhancement} % % \begin{macro}{\`name`} % We define a shortcut for +\csname+...+\endcsname+ all along this package. % \begin{macrocode} \let\kcmd@AtEnd=\` \def\`#1`{\csname #1\endcsname} % \end{macrocode} % \end{macro} % \fi % % \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. % % \begin{macrocode} \def\kcmd@keydef#1#2#3#4#5{% #1=\global(eventually), #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} % \end{macrocode} % \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}. % % \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} % \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+: % % \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}} % \end{macrocode} % \end{macro} % % \subsection{The \cs{keycmd} prefix} \label{subsec:keycmd} % % |\keycmd| acts just like a (expandable) prefix for |\def| or |\edef|: % % The syntax is:§ % \begin{tabbing} % %\qquad\= +\keycmd+\=\textcolor{red}{\textasteriskcentered} \hskip6cm \textcolor{red}{\textasteriskcentered}\,\= optional\\ % \>\> {(\color{red}+\protected|\long|\outer|\global+})\> optional \\ % \>\> (+\def|\gdef|\edef|\xdef+)\> required \\ % \>\> +\CommandWithKeys+ \> Name of the command to define \\ % \>\> +[key=value pairs]+ \> keys and default values \\ % \>\> \textcolor{red}{\emph{parameter string}} \> optional (same syntax as |\def|) \\ % \>\> +{+ \emph{replacement text} +}+ \> required % \end{tabbing} % % 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{macrocode} \DeclareRobustCommand\keycmd{\@star@or@long\kcmd@prefix} % \end{macrocode} % \end{macro} % % \begin{macro}{\kcmd@prefix} % 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{macrocode} \def\kcmd@prefix{\begingroup \let\kcmd@gbl\@empty \def\kcmd@prfx{\l@ngrel@x}% \futurelet\x\kcmd@pref@x} \def\kcmd@pref@x{% \ifx\x\@sptoken \let\next\kcmd@pref@x@space \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@pref@x@next{\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 \def\next{\kcmd@error{a \string\def\space was expected after \string\keycmd.}}% \fi\fi\fi\fi \fi\fi\fi\fi \fi\next} \begingroup\def\:{\kcmd@pref@x@space} \expandafter\gdef\: {\futurelet\x\kcmd@pref@x} \endgroup \def\kcmd@addto@prfx#1{\expandafter\def\expandafter \kcmd@prfx\expandafter{\kcmd@prfx#1}\kcmd@pref@x@next} \def\kcmd@pref@x@next{\futurelet\x\kcmd@pref@x} \def\kcmd@error#1{\@latex@error{#1}\@ehd} % \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{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} % \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@+: % \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}} % \end{macrocode} % \end{macro} % % \begin{macro}{\kcmd@def} % +\kcmd@def+ will define the keys and the command itself: % \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 \protected\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}} % \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{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} % \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{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} % \end{macrocode} % \end{macro} % % \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} % \end{macrocode} % % \begin{macrocode} \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} % \end{macrocode} % % \begin{macrocode} \def\provide@keycommand#1{\begingroup \escapechar\m@ne\edef\@gtempa{{\string#1}}% \expandafter\@ifundefined\@gtempa {\endgroup\new@keycommand#1} {\endgroup\let\kcmd@notdefinable\noexpand \renew@keycommand\kcmd@notdefinable}} % \end{macrocode} % % \subsection{new key-environments} % % \begin{macrocode} \DeclareRobustCommand\newkeyenvironment{\@star@or@long\new@keyenvironment} \DeclareRobustCommand\renewkeyenvironment{\@star@or@long\renew@keyenvironment} % \end{macrocode} % % \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}} % \end{macrocode} % % \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 \new@keyenvironment{#1}} % \end{macrocode} % % \subsection{\xpackage{kvsetkeys} correction} % % |\kv@normalize| inserts an unwilling blank space due to a small error in the code. % Mr Oberdiek has been asked for correction... % % \begin{macrocode} \def\kv@normalize#1{% \begingroup \toks@{,#1,}% \KVS@Comma \KVS@SpaceComma{ }% \KVS@CommaSpace \KVS@CommaComma \KVS@Equals \KVS@SpaceEquals{ }% \KVS@EqualsSpace% \KVS@EqualsSpace{ } \xdef\KVS@Global{\the\toks@}% \endgroup \let\kv@list\KVS@Global } % \end{macrocode} % % \begin{macrocode} % % \end{macrocode} % % \section{Example} % % \begin{macrocode} %<*example> \ProvidesFile{keycommand-example} \documentclass{article} \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} \usepackage[american]{babel} \usepackage{keycommand} \usepackage{framed} % \makeatletter \parindent\z@ \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]{% \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@]{% \def\FrameCommand{% \vrule\@width\commandkey{first}% \hskip\commandkey{sep} \vrule\@width\commandkey{second}% \hspace{\commandkey{left}}}% \parindent\z@ \MakeFramed {\advance\hsize-\width \FrameRestore}} {\endMakeFramed} % \makeatother \begin{document} \title{This is {\tt keycommand-example.tex}} \author{Florent Chervet} \date{July 22, 2009} \maketitle \section{Example of a keycommand : \texttt{\string\Rule}} \begin{tabular*}\textwidth{rl} \verb+\Rule[width=2em]{hello}+:&\Rule[width=2em]{hello}\cr \verb+\Rule[thick=1pt,width=2em]{hello}+:&\Rule[thick=1pt,width=2em]{hello}\cr \verb+\Rule{hello}+:&\Rule{hello}\cr \verb+\Rule[thick=1pt,raise=1ex]{hello}+:&\Rule[thick=1pt,raise=1ex]{hello} \end{tabular*} \section{Example of a keycommand : \texttt{\string\charfill}} \begin{tabular*}\textwidth{rp{.4\textwidth}} \verb+\charfill{$\star$}+: & \charfill{$\star$}\cr \verb+\charfill[sep=2]{$\star$}+: & \charfill[sep=2]{$\star$} \\ \verb+\charfill[sep=.7]{\textasteriskcentered}+: & \charfill[sep=.7]{\textasteriskcentered} \end{tabular*} \section{Example of a keyenvironment : \texttt{dblruled}} \verb+\begin{dblruled}+\par \verb+ test for dblruled key-environment\par+\par \verb+ test for dblruled key-environment\par+\par \verb+ test for dblruled key-environment+\par \verb+\end{dblruled}+ \begin{dblruled} test for dblruled key-environment\par test for dblruled key-environment\par test for dblruled key-environment \end{dblruled} \verb+\begin{dblruled}[first=4pt,sep=2pt,second=.6pt,left=.2em]+\par \verb+ test for dblruled key-environment\par+\par \verb+ test for dblruled key-environment\par+\par \verb+ test for dblruled key-environment+\par \verb+\end{dblruled}+ \begin{dblruled}[first=4pt,sep=2pt,second=.6pt,left=.2em] test for dblruled key-environment\par test for dblruled key-environment\par test for dblruled key-environment \end{dblruled} \end{document} % % \end{macrocode} % % \begin{thebibliography}{9} % % \bibitem{kvsetkeys} % Heiko Oberdiek: % \textit{The \xpackage{kvsetkeys} package}; % 2007/09/29 v1.3; % \CTAN{macros/latex/contrib/oberdiek/kvsetkeys.dtx}. % % \bibitem{keyval} % David Carlisle: % \textit{The \xpackage{keyval} package}; % 1999/03/16 v1.13; % \CTAN{macros/latex/required/graphics/keyval.dtx}. % % \end{thebibliography} % % \PrintIndex % % \label{LastPage} % \Finale