====== Key-value input for macros and package options ======
When we discussed
[[FAQ-moren9|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
[[ctanpkg>keyval|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
[[ctanpkg>keyval|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 [[ctanpkg>keyval|keyval]].)
These simple commands are enough, in fact, to process the botanical
example offered as replacement for multi-argument commands in
[[FAQ-moren9|the question mentioned above]], or the
optional arguments of the ''\includegraphics'' command of the
[[ctanpkg>graphicx|graphicx]] package. (The last is, in fact, what
[[ctanpkg>keyval|keyval]] was designed to do.)
However, we need more if we're to to have package options in
"key-value" form. Packages like [[ctanpkg>hyperref|hyperref]] have enormously
complicated package options which need key-value processing at
''\ProcessOptions'' time: [[ctanpkg>keyval|keyval]] can't do that on its own.
Heiko Oberdiek's [[ctanpkg>kvoptions|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
[[ctanpkg>keyval|keyval]] and may remain available for use within the document,
or may be "cancelled" to avoid confusion. If you have loaded
[[ctanpkg>kvoptions|kvoptions]], the LaTeX kernel's ''\DeclareOption'' becomes
''\DeclareVoidOption'' (it's an option with no value), and
''\DeclareOption*'' becomes ''\DeclareDefaultOption''.
Heiko also provides [[ctanpkg>kvsetkeys|kvsetkeys]] which is a more robust version
of [[ctanpkg>latex-tools|setkeys]], with some of the rough edges made smoother.
Hendri Adriaens' [[ctanpkg>xkeyval|xkeyval]] offers more flexibility than
the original [[ctanpkg>keyval|keyval]] and is more robust than the original,
too. Like [[ctanpkg>kvoptions|kvoptions]], the package also has mechanisms to
allow class and package options in key-value form (macros
''\DeclareOptionX'', ''\ExecuteOptionsX'' and ''\ProcessOptionsX''.
[[ctanpkg>Pstricks|Pstricks]] bundle packages use a [[ctanpkg>xkeyval|xkeyval]] derivative
called [[ctanpkg>pst-xkey|pst-xkey]] for their own key-value manipulation.
The (widely-respected) [[ctanpkg>pgf|pgf]] graphics package has its own
key-value package called [[ctanpkg>pgfkeys|pgfkeys]]. The documentation of the
package (part of the huge [[ctanpkg>pgf|pgf]] manual, in part 5,
"utilities") contains a useful comparison with other key-value
systems; some notable differences are:
* key organisation: [[ctanpkg>pgfkeys|pgfkeys]] uses a tree structure, while [[ctanpkg>keyval|keyval]] and [[ctanpkg>xkeyval|xkeyval]] both associate keys with a family;
* [[ctanpkg>pgfkeys|pgfkeys]] supports multi-argument key code; and
* [[ctanpkg>pgfkeys|pgfkeys]] 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 [[ctanpkg>pgfkeys|pgfkeys]] keys as part of the
options of another package, in the way that [[ctanpkg>kvoptions|kvoptions]] does.
The [[ctanpkg>l3kernel|l3kernel]] programming layer for [[FAQ-LaTeX3|LaTeX3]]
includes the [[ctanpkg>l3kernel|l3keys]] module. Inspired by [[ctanpkg>pgfkeys|pgfkeys]],
it provides a keyval-based method for the programmer to create keys.
As with keyval and derivatives, [[ctanpkg>l3kernel|l3keys]] uses separate macros
for defining and setting keys. The package [[ctanpkg>l3keys2e|l3keys2e]] makes
it possible for LaTeX2e class and package
options to be processed using [[ctanpkg>l3kernel|l3keys]]. [[ctanpkg>l3kernel|L3kernel]]
code can be used within existing LaTeX2e documents, so
[[ctanpkg>l3kernel|l3keys]] is also available to the LaTeX2e programmer "direct".
Another key-value system that's part of larger set of macros is
[[ctanpkg>scrbase|scrbase]], which uses the facilities of [[ctanpkg>keyval|keyval]] to
build a larger set of facilities, originally for use within the
[[ctanpkg>koma-script|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
[[ctanpkg>keyval|keyval]] or of [[ctanpkg>xkeyval|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 [[ctanpkg>scrbase|scrbase]] is part of the [[ctanpkg>koma-script|KOMA-script]]
bundle; so its keys are all members of the [[ctanpkg>scrbase|scrbase.sty]]
family within the [[ctanpkg>koma-script|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 [[ctanpkg>kvoptions|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 [[ctanpkg>scrbase|scrbase]] prepared by Philipp
Stephani.
All the above are (at least) aimed at LaTeX programming; there is
one package, [[ctanpkg>getoptk|getoptk]], aimed at the Plain TeX programmer.
[[ctanpkg>Getoptk|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.
-----
//Source:// [[faquk>FAQ-keyval|Key-value input for macros and package options]]
{{htmlmetatags>metatag-keywords=(LaTeX,programming)
metatag-og:title=(Key-value input for macros and package options)
metatag-og:site_name=(FAQ LaTeX francophone)
}}