%% $ITI: keyvald.dtx,v 1.2 1995/08/25 19:00:31 schrod Exp $ %%------------------------------------------------------------ %% (history at end) % % \iffalse %% File: keyvald.dtx; changed version of %% File: keyval.dtx Copyright (C) 1993-1994 David Carlisle % %<*dtx> \ProvidesFile{keyvald.dtx} % %<*!plain> %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{keyvald} % \ProvidesFile{keyvald.drv} % \fi % \ProvidesFile{keyvald.dtx} [1994/08/23 v1.08.1 key=value parser (DPC) w/ defaults (js)] % % \iffalse % %<*driver> \documentclass{ltxdoc} \usepackage{keyvald} \begin{document} \DocInput{keyvald.dtx} \end{document} % % \fi % % \GetFileInfo{keyvald.dtx} % \title{The \textsf{keyvald} package\thanks{This file % has version number \fileversion, last % revised \filedate.}} % \author{David Carlisle\\carlisle@cs.man.ac.uk % \and % changed by\\Joachim Schrod\\ % \texttt{} % } % \date{\filedate} % \maketitle % % \begin{abstract} % A \LaTeX\ package implementing a system allowing the setting % of parameters (or `named arguments' with a % \meta{key}${}={}$\meta{value} syntax. % % Eg: |\foo[height=3in, shadow = true ]{bar}| % \end{abstract} % % \CheckSum{110} % % \changes{v1.03} % {1993/10/13}{Initial version} % \changes{v1.04}{1993/11/15} % {Upgrade after comments from Timothy van Zandt} % \changes{v1.05}{1993/11/17} % {Further small improvements} % \changes{v1.06}{1994/02/01} % {Update to LaTeX2e} % \changes{v1.07}{1994/03/15} % {New style ltxdoc} % \changes{v1.08}{1994/09/12} % {Improve docstrip handling} % \changes{v1.08.1}{1995/08/23} % {Default keys} % % % This package implements a system of defining and using sets of % parameters, which are set using the syntax \meta{key}=\meta{value}. % % For each keyword in such a set, there exists a function which is % called whenever the parameter appears in a parameter list. For % instance if the set |dpc| is to have the keyword |scale| then I % would define.\\ % | \define@key{dpc}{scale}{scale ({\tt\string#1})\\}|\\ % The first argument of |\define@key| is the set of keywords being % used, the second is the keyword, and the third is the function to % call. This function will be given as |#1| the \meta{value} specified % by the user. % % Normally it is an error to omit the `=\meta{value}' however if an % optional \meta{value} is supplied when the keyword is defined, then % just the keyword need be supplied.\\ % |\define@key{dpc}{clip}[true]{...}|\\ % For `|clip|' you can go `|clip = true|' or `|clip = false|' or % just `|clip|', which is the same as `|clip = true|' % % To use these keywords, just call `|\setkeys|' with a comma % separated list of settings, each of the form % \meta{key}=\meta{value}, or just \meta{key}. Any white space around % the `|=|' and `|,|' is ignored. % % As the \meta{key} is passed as a macro argument, if it consists % entirely of a |{ }| group, the outer braces are stripped off. Thus % |,key=foo,| and |key=,{foo},| are equivalent. This fact enables one to % `hide' any commas or equals signs that must appear in the value. i.e.\ % in |foo={1,2,3},bar=4|, |foo| gets the value |1,2,3|, the comma after % |1| does not terminate the keyval pair, as it is `hidden' by the % braces. % % Empty entries, with nothing between the commas, are silently ignored. % This means that it is not an error to have a comma after the last % term, or before the first. % % \section{Example} % % We may extend the examples above to give a `fake' graphics % inclusion macro, with a syntax similar to that used in the psfig % macros. % % \makeatletter % \def\dpcgraphics{\@ifnextchar[\@dpcgraphics{\@dpcgraphics[]}} % % |\dpcgraphics| has one optional argument which is passed through % |\setkeys|, and one mandatory argument, the filename. It actually % just typesets its arguments, for demonstration. % % \def\@dpcgraphics[#1]#2{{\setkeys{dpc}{#1}INPUT: #2}}% % % \define@key{dpc}{scale}{scale ({\tt\string#1\relax})\\} % \define@key{dpc}{height}{height ({\tt#1})\\} % \define@key{dpc}{width}{width ({\tt#1})\\} % \define@key{dpc}{bb}{bounding box ({\tt#1})\\} % \define@key{dpc}{clip}[true]{clip ({\tt\string#1\relax})\\} % \makeatother % % The declared keys are: |scale|, |height|, |width|, |bb|, % and |clip|. Except for the last, they must all be given a value if % used. % % Note how in the following, any white space arround |=| or |,| is % ignored, as are the `empty' arguments caused by extra commas. Note % also that each macro receives {\em exactly\/} the tokens that you % specify as arguments, no premature expansion is done. % % \begin{verbatim} % \def\dpcgraphics{\@ifnextchar[\@dpcgraphics{\@dpcgraphics[]}} % \def\@dpcgraphics[#1]#2{{\setkeys{dpc}{#1}INPUT: #2}} % % \define@key{dpc}{scale}{scale ({\tt\string#1\relax})\\} % \define@key{dpc}{clip}[true]{clip ({\tt\string#1\relax})\\} % \end{verbatim} % % \begin{minipage}{.4\textwidth} % \begin{verbatim} % \def\scalemacro{9} % \dpcgraphics % [ height =4in, , % width = 3in, % scale = \scalemacro, % bb = 20 20 300 400 , % clip, % ]{aaa} % \end{verbatim} % \end{minipage} % \hfill % \begin{minipage}{.4\textwidth} % \def\scalemacro{9} %\dpcgraphics % [ height =4in, , % width = 3in, % scale = \scalemacro , % bb = 20 20 300 400 , % clip , % ]{aaa} % \end{minipage} % % % \section{The Internal Interface} % A declaration of the form:\\ % |\define@key{family}{key}{...}|\\ % Defines a macro |\KV@prefix@key| with one argument. When used in a % keyval list, the macro receives the value as its argument. % % A declaration of the form:\\ % |\define@key{family}{key}[default]{...}|\\ % Defines a macro |\KV@family@key| as above, however it also defines the % macro |\KV@family@key@default| as a macro with no arguments, and % definition\\ % |\KV@family@key{default}|. % % Thus if macros are defined using |\define@key|, the use of a key with % no value \ldots|,foo,|\ldots\ is always equivalent to the use of the % key with some value, \ldots|,foo=default,|\ldots. However a package % writer may wish that the `default' behaviour for some key is not % directly equivalent to using that key with a value. (In particular, as % pointed out to me by Timothy Van Zandt, you may wish to omit error % checking on the default value as you know it is correct.) In these % cases one simply needs to define the two macros % |\KV@|\meta{family}|@key| and |\KV@|\meta{family}|@key@default| % directly using |\def| (or |\newcommand|). I do not supply a user % interface for this type of definition, but it is supported in the % sense that I will try to ensure that any future upgrades of this % package do not break styles making use of these `low level' % definitions. % % \StopEventually{} % % \section{The Macros} % % From version~1.05, all `internal' macros associated to keys have names % of the form:\\ % |\KV@|\meta{family}|@|\meta{key} or % |\KV@|\meta{family}|@|\meta{key}|@|\meta{default} % % \begin{macrocode} %<*package> % \end{macrocode} % % \begin{macro}{\setkeys} % The top level macro. |#2| should be a comma separated values of the % form \meta{key} |=| \meta{value} or just simply \meta{key}. % The macro associated with this key in the `family' |#1| is called with % argument \meta{value}. The second form is only allowed if the key was % declared with a default value. % \begin{macrocode} \def\setkeys#1#2{% % \end{macrocode} % Save the `family' for later. Then begin acting on the comma % separated list. % \begin{macrocode} \def\KV@prefix{KV@#1@}% \KV@do#2,\relax,} % \end{macrocode} % \end{macro} % % \begin{macro}{\KV@do} % Iterate down the list of comma separated argument pairs. % \begin{macrocode} \def\KV@do#1,{% \ifx\relax#1\empty\else \KV@split#1==\relax \expandafter\KV@do\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\KV@split} % Split up the keyword and value, and call the appropriate command. % This macro was slightly reorganised for version 1.04, after some % suggestions from Timothy Van Zandt. % \begin{macrocode} \def\KV@split#1=#2=#3\relax{% \KV@@sp@def\KV@key{#1}% \ifx\KV@key\@empty\else \expandafter\let\expandafter\@tempc \csname\KV@prefix\KV@key\endcsname \ifx \@tempc\relax \expandafter\let \expandafter\@tempc \csname\KV@prefix*\endcsname \def\@tempa{*}% \else \let\@tempa\KV@key \fi \ifx\@tempc\relax \KV@err{\KV@key\space undefined}% \else \ifx\@empty#3\@empty \KV@default \else \KV@@sp@def\@tempb{#2}% \expandafter\@tempc\expandafter{\@tempb}\relax \fi \fi \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\KV@default} % Run the default code, or raise an error. % \begin{macrocode} \def\KV@default{% \expandafter\let\expandafter\@tempb \csname\KV@prefix\@tempa @default\endcsname \ifx\@tempb\relax \KV@err{No value specified for \KV@key}% \else \@tempb\relax \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\KV@err} % Error messages. % \begin{macrocode} \def\KV@err#1{\PackageError{keyvald}{#1}{}} % \end{macrocode} % \end{macro} % % \begin{macro}{\KV@@sp@def} % \begin{macro}{\KV@@sp@b} % \begin{macro}{\KV@@sp@c} % |\KV@@sp@def|\meta{cmd}\meta{token list} is like |\def|, except that % a space token at the beginning or end of \meta{token list} is % removed before making the assignment. \meta{token list} may not % contain the token |\@nil|, unless it is within a brace group. % The names of these commands were changed at version~1.05 to ensure % that they do not clash with `internal' macros in a key family `sp'. % % The following three lines are equivalent to\\ % |\def\KV@@sp@def#1#2{\KV@@sp@b#2\@nil\@nil~\@nil\relax#1}|\\ % Where |~| is an explicit space token. % \begin{macrocode} \def\@tempa#1{% \def\KV@@sp@def##1##2{\KV@@sp@b##2\@nil\@nil#1\@nil\relax##1}} \@tempa{ } \def\KV@@sp@b#1#2 \@nil{\KV@@sp@c#1#2} \def\KV@@sp@c#1\@nil#2\relax#3{\def#3{#1}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\define@key} % Define the command associated to the key |#2| in the family |#1|. % First looks for a default argument (the default value for the % key) % \begin{macrocode} \def\define@key#1#2{% \@ifnextchar[{\KV@def{#1}{#2}}{\@namedef{KV@#1@#2}####1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\KV@def} % Make the definitions of the command, and the default value. % \begin{macrocode} \def\KV@def#1#2[#3]{% \@namedef{KV@#1@#2@default\expandafter}\expandafter {\csname KV@#1@#2\endcsname{#3}}% \@namedef{KV@#1@#2}##1} % \end{macrocode} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % \Finale % \endinput %------------------------------------------------------------ % % $ITIlog: keyvald.dtx,v $ % Revision 1.2 1995/08/25 19:00:31 schrod % Add enhanced version of keyval package, with ability to specify % default action for unknown keyword options. %