The Keyval Package
The Keyval Package
The Keyval Package
David Carlisle
2014/10/28
Abstract
A LATEX package implementing a system allowing the setting of param-
eters (or ‘named arguments’ with a hkeyi = hvaluei syntax.
Eg: \foo[height=3in, shadow = true ]{bar}
1
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 around = 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)
[ height =4in, ,
width (3in)
width = 3in,
scale (\scalemacro)
scale = \scalemacro,
bb = 20 20 300 400 , bounding box (20 20 300 400)
clip, clip (true)
]{aaa} INPUT: aaa
2
\KV@hfamilyi@key@default directly using \def (or \newcommand). I do not sup-
ply 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@hfamilyi@hkeyi or \KV@hfamilyi@hkeyi@hdefaulti
1 h∗packagei
\setkeys The top level macro. #2 should be a comma separated values of the form hkeyi =
hvaluei or just simply hkeyi. The macro associated with this key in the ‘family’
#1 is called with argument hvaluei. The second form is only allowed if the key was
declared with a default value.
2 \long\def\setkeys#1#2{%
Save the ‘family’ for later. Then begin acting on the comma separated list.
3 \def\KV@prefix{KV@#1@}%
4 \let\@tempc\relax
5 \KV@do#2,\relax,}
\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.
10 \long\def\KV@split#1=#2=#3\relax{%
11 \KV@@sp@def\@tempa{#1}%
12 \ifx\@tempa\@empty\else
13 \expandafter\let\expandafter\@tempc
14 \csname\KV@prefix\@tempa\endcsname
15 \ifx\@tempc\relax
16 hplaini \KV@err
17 h!plaini \KV@errx
18 {\@tempa\space undefined}%
19 \else
20 \ifx\@empty#3\@empty
21 \KV@default
22 \else
23 \KV@@sp@def\@tempb{#2}%
24 \expandafter\@tempc\expandafter{\@tempb}\relax
25 \fi
26 \fi
3
27 \fi}
\KV@@sp@def \KV@@sp@defhcmd ihtoken listi is like \def, except that a space token at the begin-
\KV@@sp@b ning or end of htoken listi is removed before making the assignment. htoken listi
\KV@@sp@c may not contain the token \@nil, unless it is within a brace group. The names
\KV@@sp@d of these commands were changed at version 1.05 to ensure that they do not clash
with ‘internal’ macros in a key family ‘sp’.
Since v1.10, # may appear in the second argument without it needing to be
doubled as ##. Also earlier versions would drop any initial brace group, so {abc}d
would incorrectly be treated as abcd. The current version only removes brace
groups that surround the entire value, so {abcd} is treated correctly as abcd.
Prior to v1.14, two levels of bracing are removed, if you require the entire argument
to be a single brace group, you had use {{{abcd}}}, from v1.14 exactly one brace
group is removed, so to make the entire value be a brace group you need {{abc}}.
46 \def\@tempa#1{%
47 \long\def\KV@@sp@def##1##2{%
48 \futurelet\KV@tempa\KV@@sp@d##2\@nil\@nil#1\@nil\relax##1}%
Early release removed initial space by having an ‘extra’ argument in \KV@@sp@b
but that removed too many braces, so now make \KV@@sp@b explicitly remove
a single space token. That unfortunately means we need the new \KV@@sp@d
command to add a space token if one was not there before.
49 \def\KV@@sp@d{%
50 \ifx\KV@tempa\@sptoken
51 \expandafter\KV@@sp@b
52 \else
4
53 \expandafter\KV@@sp@b\expandafter#1%
54 \fi}%
55 \long\def\KV@@sp@b#1##1 \@nil{\KV@@sp@c##1}%
56 hplaini\def\@sptoken{#1}%
Make the above definitions, inserting the space token where needed.
57 }
58 \@tempa{ }
59 \long\def\KV@@sp@c#1\@nil#2\relax#3{\KV@toks@{#1}\edef#3{\the\KV@toks@}}
\KV@toks@ Macro register used above to prevent # doubling. Avoid uding one of the normal
scratch registers, as this code is not in a local group.
60 \newtoks\KV@toks@
\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)
61 \def\define@key#1#2{%
62 \@ifnextchar[{\KV@def{#1}{#2}}{\long\@namedef{KV@#1@#2}####1}}
\KV@def Make the definitions of the command, and the default value.
63 \def\KV@def#1#2[#3]{%
64 \long\@namedef{KV@#1@#2@default\expandafter}\expandafter
65 {\csname KV@#1@#2\endcsname{#3}}%
66 \long\@namedef{KV@#1@#2}##1}
67 h/packagei