# How to code the \key@ifundefined from the xkeyval package?

I looked at the xkeyval package documentation and did my best to follow it. However, I cannot get the \key@ifundefined coded so that it will compile and work.

Here is my MWE with the offending lines commented out.

The existing behavior is that I get embedded blank lines in my list for the keys that are not defined in the calling parameters.

The desired functionality is to skip printing those empty values and not have blank lines in the printing. I thought the \key@ifundefined could help me with that...

% !TeX root = mwe.tex
\documentclass[12pt,a4paper,titlepage,english]{article}

\usepackage{xkeyval}

%% Start definitions using KEYS
\makeatletter
\define@key{ingredientlanguage}{englishname}[]{\gdef\Zenglishname{#1}}
\define@key{ingredientlanguage}{thainame}[]{\gdef\Zthainame{#1}}
\define@key{ingredientlanguage}{burmesename}[]{\gdef\Zburmesename{#1}}
\define@key{ingredientlanguage}{khmername}[]{\gdef\Zkhmername{#1}}

\makeatother
%%  End Definitions using KEYS

\begingroup

\setkeys{ingredientlanguage}{#1}

%   \key@ifundefined{ingredientlanguage}{burmesename}{undefined}{defined}

%
%   {\Zenglishname}\\
%   \key@ifundefined{ingredientlanguage}{burmesename}{}{{\Zburmesename}\\}
%   {\Zthainame}\\
%   {\Zkhmername}\\

{\Zenglishname}\\
{\Zburmesename}\\
{\Zthainame}\\
{\Zkhmername}\\

\endgroup
}

\newcommand{\zixxFone}{

englishname=Star Fruit,
thainame=mafeung,
khmername,
burmesename=qwerty}

}

\newcommand{\zixxFtwo}{

englishname=Star Fruit,
thainame=mafeung,
khmername,
burmesename=}

}

\begin{document}

\zixxFone

\rule{\textwidth}{3pt}

\zixxFtwo

\end{document}


If I understand the xkeyval documentation correctly \key@ifundefined only checks if you have given a key definition with \define@key. As such \key@ifundefined will always be false for {ingredientlanguage}{burmesename} because you have given a definition for that key in \define@key{ingredientlanguage}{burmesename}[]{\gdef\Zburmesename{#1}}. \key@ifundefined is probably not what you are looking for.

To get the desired result you should test whether or not the macros to which you write the data are empty or not. This can be done with etoolbox's \ifdefvoid, e.g.

\ifdefvoid\Zburmesename
{<\Zburmesename is empty>}
{<\Zburmesename is not empty>}


Which will probably be used as follows. (Note that I changed from global assignment with \gdef to local assignment with \def. That should avoid weird side effects when keys are not given. At least in the example you don't need the global assignments - and if you want a re-usable \setkeys macro you should probably code it in a way avoiding global assignments.)

\documentclass[12pt,a4paper]{article}

\usepackage{etoolbox}
\usepackage{xkeyval}
\makeatletter
\define@key{ingredientlanguage}{englishname}[]{\def\Zenglishname{#1}}
\define@key{ingredientlanguage}{thainame}[]{\def\Zthainame{#1}}
\define@key{ingredientlanguage}{burmesename}[]{\def\Zburmesename{#1}}
\define@key{ingredientlanguage}{khmername}[]{\def\Zkhmername{#1}}
\makeatother

\begingroup
\setkeys{ingredientlanguage}{#1}%
\Zenglishname\\
\ifdefvoid\Zburmesename
{}
{\Zburmesename\\}%
\Zthainame\\
\ifdefvoid\Zkhmername
{}
{\Zkhmername\\}%
\endgroup
}
\makeatother

\newcommand{\zixxFone}{%
englishname=Star Fruit,
thainame=mafeung,
khmername,
burmesename=qwerty}%
}

\newcommand{\zixxFtwo}{%
englishname=Star Fruit,
thainame=mafeung,
khmername=,
}%
}

\begin{document}
\zixxFone
\rule{\textwidth}{3pt}
\zixxFtwo
\end{document}


Depending on what you are actually trying to do there may be much more elegant methods available.

• I tried it and it seems like it works. Thanks for helping clarify the use of the xkeval/etools. I don't need a global def but just copied other working examples without understanding. I was a little concerned that your run output showed qwerty in both outputs, but qwerty is only passed in '\zixxFone' and not in \zixxFtwo'. – mkstreet May 26 '20 at 0:05
• @mkstreet Oh yes, the picture was from a version using \gdefs (I only noticed them at the very end). Picture updated. – moewe May 26 '20 at 3:25
• Ah ok! Well, your solution seems great. Thanks much,. I will mark it as accepted. – mkstreet May 27 '20 at 22:54