The keyval package^{∗}

David Carlisle carlisle@cs.man.ac.uk

1995/09/21

Abstract

A L^{A}TEX package implementing a system allowing the setting of parameters (or ‘named arguments’ with a ⟨key⟩ = ⟨value⟩ syntax.

        Eg: \foo[height=3in, shadow = true ]{bar}

This package implements a system of defining and using sets of parameters, which are set using the syntax ⟨key⟩=⟨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 ⟨value⟩ specified by the user.

Normally it is an error to omit the ‘=⟨value⟩’ however if an optional ⟨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 ⟨key⟩=⟨value⟩, or just ⟨key⟩. Any white space around the ‘=’ and ‘,’ is ignored.

As the ⟨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.

∗This file has version number v1.09, last revised 1995/09/21.

1 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.

\dpcgraphics has one optional argument which is passed through \setkeys, and one mandatory argument, the filename. It actually just typesets its arguments, for demonstration.

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 exactly the tokens that you specify as arguments, no premature expansion is done.

 \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})\\}
    \def\scalemacro{9}
    \dpcgraphics
    [ height =4in, ,
      width = 3in,
      scale = \scalemacro,
      bb = 20 20 300 400 ,
      clip,
     ]{aaa}

height (4in) width (3in)

                                         scale (\scalemacro)

bounding box (20 20 300 400) clip (true) INPUT: aaa

2 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 …,foo,… is always equivalent to the use of the key with some value, …,foo=default,…. 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@⟨family⟩@key and \KV@⟨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.

3 The Macros

From version 1.05, all ‘internal’ macros associated to keys have names of the form: \KV@⟨family⟩@⟨key⟩ or \KV@⟨family⟩@⟨key⟩@⟨default⟩

1 ⟨∗package⟩

\setkeys The top level macro. #2 should be a comma separated values of the form ⟨key⟩ = ⟨value⟩ or just simply ⟨key⟩. The macro associated with this key in the ‘family’ #1 is called with argument ⟨value⟩. The second form is only allowed if the key was declared with a default value.

 2 \def\setkeys#1#2{%

Save the ‘family’ for later. Then begin acting on the comma separated list.

 3 \def\KV@prefix{KV@#1@}%
 4 \KV@do#2,\relax,}

\KV@do Iterate down the list of comma separated argument pairs.

 5 \def\KV@do#1,{%
 6 \ifx\relax#1\empty\else
 7 \KV@split#1==\relax
 8 \expandafter\KV@do\fi}

\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.

 9 \def\KV@split#1=#2=#3\relax{%
10 \KV@@sp@def\@tempa{#1}%
11 \ifx\@tempa\@empty\else
12  \expandafter\let\expandafter\@tempc
13  \csname\KV@prefix\@tempa\endcsname
14  \ifx\@tempc\relax
15  \KV@err{\@tempa\space undefined}%
16  \else
17  \ifx\@empty#3\@empty
18  \KV@default
19  \else
20  \KV@@sp@def\@tempb{#2}%
21  \expandafter\@tempc\expandafter{\@tempb}\relax
22  \fi
23  \fi
24 \fi}

\KV@default Run the default code, or raise an error.

25 \def\KV@default{%
26 \expandafter\let\expandafter\@tempb
27  \csname\KV@prefix\@tempa @default\endcsname
28 \ifx\@tempb\relax
29  \KV@err{No value specified for \@tempa}%
30 \else
31  \@tempb\relax
32 \fi}

\KV@err Error messages.

33 \def\KV@err#1{\errmessage{key-val: #1}}

\KV@@sp@def \KV@@sp@b \KV@@sp@c \KV@@sp@def⟨cmd⟩⟨token list⟩ is like \def, except that a space token at the beginning or end of ⟨token list⟩ is removed before making the assignment. ⟨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.

34 \def\@tempa#1{%
35 \def\KV@@sp@def##1##2{\KV@@sp@b##2\@nil\@nil#1\@nil\relax##1}}
36 \@tempa{ }
37 \def\KV@@sp@b#1#2 \@nil{\KV@@sp@c#1#2}
38 \def\KV@@sp@c#1\@nil#2\relax#3{\def#3{#1}}

\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)

39 \def\define@key#1#2{%
40 \@ifnextchar[{\KV@def{#1}{#2}}{\@namedef{KV@#1@#2}####1}}

\KV@def Make the definitions of the command, and the default value.

41 \def\KV@def#1#2[#3]{%
42 \@namedef{KV@#1@#2@default\expandafter}\expandafter
43  {\csname KV@#1@#2\endcsname{#3}}%
44 \@namedef{KV@#1@#2}##1}

45 ⟨/package⟩

Change History

v1.03

General: Initial version . . . . . . . . 1 v1.04

General: Upgrade after comments from Timothy van Zandt . . . . . 1 v1.05

General: Further small improve-

ments . . . . . . . . . . . . . . . . . . . 1 v1.06

General: Update to LaTeX2e …. 1 v1.07

General: New style ltxdoc . . . . . . 1 v1.08

General: Improve docstrip han-

dling . . . . . . . . . . . . . . . . . . . 1 v1.09

General: Move a comma for graphics/1698 . . . . . . . . . . . . . . . . . 1

Index

Numbers written in italic refer to the page where the corresponding entry is described, the ones underlined to the code line of the definition, the rest to the code lines where the entry is used.

Symbols

\@empty . . . . . . . . 11, 17

\@ifnextchar . . . . . . 40

\@namedef … 40, 42, 44 \@nil . . . . . . . 35, 37, 38 \@tempa . . 10, 11, 13,

15, 27, 29, 34, 36 \@tempb 20, 21, 26, 28, 31 \@tempc . . . . . 12, 14, 21

C

\csname . . . . . 13, 27, 43

D

\def … 2, 3, 5, 9, 25,

33–35, 37–39, 41

\define@key . . . . . . . \underline{39}

E \else . . 6, 11, 16, 19, 30 \empty . . . . . . . . . . . . 6

                          \endcsname . . 13, 27, 43
                          \errmessage . . . . . . . 33
                          \expandafter . . . . . .

. . 8, 12, 21, 26, 42

F \fi . . . . . . 8, 22–24, 32

I \ifx … 6, 11, 14, 17, 28

K \KV@@sp@b . . . . . . . . \underline{34}

\KV@@sp@c . . . . . . . . \underline{34}

                          \KV@@sp@def . . 10, 20, \underline{34}

\KV@def . . . . . . . . 40, \underline{41}

                                                   \KV@default . . . . . 18, \underline{25}

\KV@do . . . . . . . . . . 4, \underline{5} \KV@err . . . . . 15, 29, \underline{33}

                                                   \KV@prefix . . . 3, 13, 27

\KV@split . . . . . . . 7, \underline{9}

L \let . . . . . . . . . . . 12, 26

R \relax . 4, 6, 7, 9, 14,

21, 28, 31, 35, 38

S \setkeys . . . . . . . . . . \underline{2} \space . . . . . . . . . . . 15