Frequently Asked Question List for TeX
When we discussed
extending the number of arguments to a macro, we
suggested that large numbers of arguments, distinguished only by their
position, aren’t very kind to the user, and that a package such as
keyval
offers a more attractive user interface. We now
consider the packages that the macro programmer might use, to create
such a user interface.
The simplest key-value processor (for LaTeX, at least) remains
keyval
; it has a command \define@key
to declare a key
and a handler to process it, and a macro \setkeys
to offer
values to the handler of one or more keys. Thus:
\define@key{my}{foo}{Foo is #1\par}
\define@key{my}{bar}[99]{Bar is #1\par}
...
\setkeys{my}{foo=3,bar}
will produce output saying: Foo is 3
Bar is 99
This has defined two keys foo
and bar
in family
my
, and then executed them, the first with argument
3
and the second with no argument, so that the default
value of 99
is picked up. In effect, the two calls to
\define@key
are simply defining commands, as (for example):
\newcommand{\KV@my@foo}[1]{Foo is #1}
(the definition of \KV@my@bar
is similar, but trickier). The
command \setkeys
knows how to find those commands when it needs to
process each key — it is easy to regurgitate the structure of the
command name, with family name (my
, here) after the first
@
, and the key name after the second @
. (The
KV
part is fixed, in keyval
.)
These simple commands are enough, in fact, to process the botanical
example offered as replacement for multi-argument commands in
the question mentioned above, or the
optional arguments of the \includegraphics
command of the
graphicx
package. (The last is, in fact, what
keyval
was designed to do.)
However, we need more if we’re to to have package options in
“key-value” form. Packages like hyperref
have enormously
complicated package options which need key-value processing at
\ProcessOptions
time: keyval
can’t do that on its own.
Heiko Oberdiek’s kvoptions
package comes to our help: it
enables the programmer to declare class or package options that
operate as key and value pairs. The package defines commands
\DeclareBoolOption
for options whose value should be either
true or false, and \DeclareStringOption
for all
other options that have a value. Keys are declared using
keyval
and may remain available for use within the document,
or may be “cancelled” to avoid confusion. If you have loaded
kvoptions
, the LaTeX kernel’s \DeclareOption
becomes
\DeclareVoidOption
(it’s an option with no value), and
\DeclareOption*
becomes \DeclareDefaultOption
.
Heiko also provides kvsetkeys
which is a more robust version
of setkeys
, with some of the rough edges made smoother.
Hendri Adriaens’ xkeyval
offers more flexibility than
the original keyval
and is more robust than the original,
too. Like kvoptions
, the package also has mechanisms to
allow class and package options in key-value form (macros
\DeclareOptionX
, \ExecuteOptionsX
and \ProcessOptionsX
.
Pstricks
bundle packages use a xkeyval
derivative
called pst-xkey
for their own key-value manipulation.
The (widely-respected) pgf
graphics package has its own
key-value package called pgfkeys
. The documentation of the
package (part of the huge pgf
manual, in part 5,
“utilities”) contains a useful comparison with other key-value
systems; some notable differences are:
pgfkeys
uses a tree structure, while
keyval
and xkeyval
both associate keys with a family;pgfkeys
supports multi-argument key code; andpgfkeys
can support call-backs when an unknown key
appears (these things are called handlers.Keys are organized in a tree that is reminiscent of the Unix fille
tree. A typical key might be, /tikz/coordinate system/x
or
just /x
. When you specify keys you can provide the complete
path of the key, but you usually just provide the name of the key
(corresponding to the file name without any path) and the path is
added automatically. So a \pgfkeys
command might be:
\pgfkeys{/my key=hello,/your keys/main key=something\strange,
key name without path=something else}
and for each key mentioned, the associated code will be executed.
… and that code is also set up using \pgfkeys
:
\pgfkeys{/my key/.code=The value is "#1".}
after which
\pgfkeys{/my key=hi!}
will produce just
The value is “hi!”.
The manual goes on, showing how to define a key with two arguments,
how to provide default value for a key, and how to define aliases for
particular key sequences (which are called “styles”). All in all,
it seems a well thought-out system, offering a lot of flexibility that
isn’t available with the other keys packages. However, there seems to
be no mechanism for using pgfkeys
keys as part of the
options of another package, in the way that kvoptions
does.
The l3kernel
programming layer for LaTeX3
includes the l3keys
module. Inspired by pgfkeys
,
it provides a keyval-based method for the programmer to create keys.
As with keyval and derivatives, l3keys
uses separate macros
for defining and setting keys. The package l3keys2e
makes
it possible for LaTeX2e class and package
options to be processed using l3keys
. L3kernel
code can be used within existing LaTeX2e documents, so
l3keys
is also available to the LaTeX2e programmer “direct”.
Another key-value system that’s part of larger set of macros is
scrbase
, which uses the facilities of keyval
to
build a larger set of facilities, originally for use within the
KOMA-script
bundle. For English-speaking authors, there are
difficulties from the German-only documentation; however, from a
partial translation available to the author of this answer, a summary
is possible. The package may build on the facilities either of
keyval
or of xkeyval
, and builds its functionality
on the structure of the “key family”. The user may define family
“members” and keys are defined relative to the members. (For example,
the package scrbase
is part of the KOMA-script
bundle; so its keys are all members of the scrbase.sty
family within the KOMA
family. The function
\FamilyProcessOptions
allows the programmer to decode the options
of the package in terms of the package’s key family. Note that there
is no special provision made for “traditional” package options, as
in the kvoptions
package.
This brief summary was guided by input from two sources: a draft article
for TUGboat by Joseph Wright, and the partial translation of the
documentation of package scrbase
prepared by Philipp
Stephani.
All the above are (at least) aimed at LaTeX programming; there is
one package, getoptk
, aimed at the Plain TeX programmer.
Getoptk
uses syntax inspired by that offered by TeX
primitives such as \hrule
and \hbox
, so we are offered
syntax such as:
\begindisplay file {chapter1} literal offset 20pt
(taken from the package manual).
There are (we know) people who would swear that such syntax is wonderful (the present author wouldn’t), but the package earns its place as the only stand-alone key-value macros that will work in Plain TeX.