# Detecting empty key values when key is provided

I believe I am looking for a LaTeX3 type syntax solution to more appropriately detect a missing argument. To me I would have expected key={} to be a valueless, blank, or empty argument key. After searching through questions I expected \tl_if_blank:nF and IfNoValueF to be my best bet, but either my key variable is not a compatible argument for these functions, or the key has to fail to be produced in order to return a TRUE on these functions. In the MWE below, I can tell it is still being executed because of the extra lines that get included.

I know it would be better if I could avoid including the keys when blank, but at the moment this is out of my control as someone else is responsible for the script that is parsing a database into the content filled syntax block simulated below in \SampleBlock. So I am trying to detect an empty key value but it's not working as I expected.

MWE:

\documentclass[10pt]{article}

\usepackage{xparse}

%--------------------New Commands for consistent formatting ---------------
\ExplSyntaxOn

% define the variable before using it:
\tl_new:N \l_paragraph_tl

% define key:
\keys_define:nn { Sample }
{
,   key-paragraph               .tl_set:N = \l_paragraph_tl
}

\DeclareDocumentCommand{\SampleBlock}{ o }
{
%TODO some residual debugging may be needed for omitted keys
\group_begin:% start a group to keep key setting local:
% set keys if optional argument #1 is given:
\IfNoValueF {#1} { \keys_set:nn {Sample} {#1} }

\tl_if_blank:nF{\l_paragraph_tl}{\l_paragraph_tl}

\group_end:
}

\ExplSyntaxOff

%--------------------BEGIN DOCUMENT----------------------
\begin{document}

\SampleBlock[%
key-paragraph={A paragraph of text will go here.  Maybe I will say hello world, maybe I will describe how the quick brown fox jumped over the lazy brown dog.  Really, the possibilities are endless.  Oh wait, I could have used lipsum.  Doh!}]

\medskip \medskip\medskip \medskip\medskip \medskip

\SampleBlock[%
key-heading={No subheading but there will still be a space for it on the next line...},
key-paragraph={A paragraph of text will go here.  Maybe I will say hello world, maybe I will describe how the quick brown fox jumped over the lazy brown dog.  Really, the possibilities are endless.  Oh wait, I could have used lipsum.  Doh!}]

\end{document}


\IfNoValue(TF) is used to test the presence or absence of an o argument. It has nothing to do with checking the emptiness of a token list variable, for which you have to use \tl_if_blank:V(TF). The notation (TF) means you can use TF, T or F (or nothing at all, in some cases, not this one).

Note that \tl_if_blank:nTF { \l_tmpa_tl } would always return false, because the given token list is not blank, as it contains a non space token. When you do

\tl_clear:Nn \l_tmpa_tl
\tl_if_blank:VTF \l_tmpa_tl {TRUE} {FALSE}


would return true.

\documentclass[10pt]{article}

\usepackage{xparse}

%--------------------New Commands for consistent formatting ---------------
\ExplSyntaxOn

% define the variable before using it (not really necessary)
%\tl_new:N \l_engbird_paragraph_tl

% define key:
\keys_define:nn { Sample }
{
key-paragraph  .tl_set:N = \l_engbird_paragraph_tl,
}

\DeclareDocumentCommand{\SampleBlock}{ O{} }
{
%TODO some residual debugging may be needed for omitted keys
\group_begin:% start a group to keep key setting local:
% set keys if optional argument #1 is given:
\keys_set:nn {Sample} {#1}

\tl_if_blank:VF \l_engbird_paragraph_tl {\l_engbird_paragraph_tl}

\group_end:
}

\ExplSyntaxOff

%--------------------BEGIN DOCUMENT----------------------
\begin{document}

\SampleBlock[%
key-paragraph={A paragraph of text will go here.  Maybe I will say hello world, maybe I will describe
how the quick brown fox jumped over the lazy brown dog.  Really, the possibilities are endless.  Oh
wait, I could have used lipsum.  Doh!}]

\bigskip

\SampleBlock[%
key-heading={No subheading but there will still be a space for it on the next line...},
key-paragraph={A paragraph of text will go here.  Maybe I will say hello world, maybe I will describe
how the quick brown fox jumped over the lazy brown dog.  Really, the possibilities are endless.  Oh
wait, I could have used lipsum.  Doh!}]

\end{document}


Note that \IfNoValueF{#1} for setting keys is redundant: setting no key is as good as doing nothing.

### Further notes

You can have three cases for a key, let's call it foo at point of use:

1. The key is not specified
2. You specify foo
3. You specify foo=...

For simplicity, let's assume you always set keys in a group, like in your example. When you define the key with

foo .tl_set:N = \l_whatever_foo_tl,


(or another key definition command), you can add also

foo .initial:n = INITIAL~VALUE,
foo .default:n = DEFAULT~VALUE,


The right-hand sides are empty by default. What's the difference?

1. The key foo is not set at point of use: the value used for \l_whatever_foo_tl will be INITIAL~VALUE.

2. The key foo appears without an equals sign: the value used for \l_whatever_foo_tl will be DEFAULT~VALUE.

3. The user does foo=Something: the value used for \l_whatever_foo_tl will be Something.

Another thing to note: when you have

foo .tl_set:N = \l_whatever_foo_tl,


in \keys_define:nn, the variable in the right-hand side is automatically declared, so it's not necessary to have a \tl_new:N declaration beforehand (but it doesn't harm either).

• Perhaps note that key = {} is not the same as just key? – Joseph Wright Nov 26 '15 at 9:06
• @JosephWright There is no key without an equals sign in the example. The key-subheading={} bit can be omitted, as the corresponding token list is empty by default. – egreg Nov 26 '15 at 9:58
• Yes I know, but the OP is suggesting that key = {} means that no value has been given, whereas it has (an empty value). – Joseph Wright Nov 26 '15 at 10:06