Using etoolbox’s \ifblank with xkeyval
At a glance
- 1. Load etoolbox
Load etoolbox explicitly so its \ifblank conditional is defined.
- 2. Use a key handler
Put \ifblank in the code that handles the xkeyval key’s value.
- 3. Check the exact error
An undefined command and a duplicate definition point to different problems.
The etoolbox and xkeyval packages do not inherently conflict. etoolbox provides \ifblank, and an xkeyval key handler can use it to test the value passed to a key.
Minimal working example
This complete example defines a name key. If its value is empty, the handler stores one message; otherwise, it stores the supplied value.
\documentclass{article}
\usepackage{etoolbox}
\usepackage{xkeyval}
\makeatletter
\define@key{demo}{name}{%
\ifblank{#1}%
{\def\demomessage{No name was given.}}%
{\def\demomessage{Name: #1}}%
}
\makeatother
\begin{document}
\setkeys{demo}{name={}}
\demomessage
\setkeys{demo}{name={Ada}}
\demomessage
\end{document}
The first key setting produces “No name was given.” The second produces “Name: Ada.” The \makeatletter and \makeatother lines allow use of \define@key, whose name contains @.
What \ifblank checks
The syntax is:
\ifblank{<value>}{<true branch>}{<false branch>}
The true branch runs when the argument is empty or contains only spaces; otherwise, the false branch runs. For a key handler, #1 represents the value supplied by xkeyval. In the example, name={} passes an empty value.
Load etoolbox explicitly rather than relying on another package to load it as a dependency. Loading it before xkeyval in the example also ensures the conditional is available if key-related code is executed while the document is being set up. The important point is that \ifblank must be defined by the time the handler that uses it runs.
Diagnose the error message
- “Undefined control sequence” at
\ifblank:etoolboxmay not be loaded, may be loaded too late, or the command may be misspelled. Add\usepackage{etoolbox}to the preamble before the relevant code runs. - “Command
\ifblankalready defined”: Some other loaded file has defined a command with that name. This is a name collision, not proof that the two packages are incompatible. Check the full log and reduce the document to a small example to identify which package or class defines it first. Avoid silencing the error by setting\ifblankto\relax; that can hide the collision while leaving the wrong definition in use. - The test always takes the unexpected branch: Check the actual value passed to the key.
\ifblanktests the supplied tokens; a macro that expands to nothing is not necessarily the same as an empty argument.
Common mistakes
A key handler is defined as an argument to \define@key, so its parameter is written as #1, as in the example. If you put the key definition inside another macro definition, the # must be doubled at the outer definition level—for example, ##1—because TeX first processes the surrounding macro’s parameters.
Also distinguish an empty value from a missing key. name={} sets the key to an empty value, so its handler runs and \ifblank can test that value. If the key is omitted entirely, its handler normally does not run. A default supplied with \define@key applies when the key is present without a value, not when it is omitted; if the handler must run for an omitted key, explicitly arrange for the key to be set, for example with an appropriate preset.
References
Spotted an error? Send a correction. Read how we write and check articles in our editorial policy.