5

I am sorting some tokens in a token list using the nice features of latex3 (see below command \nom). These tokens can be sometimes empty, and when they are empty they would trigger different conditions within another command, below called \amc. The problem is that when receiving the arguments in \amc they are not detected as empty. Thus, the condition is never triggered.

I have already tried with passing within \clist_if_empty:NTF \l__wdsgn_notation_subscript_clist {**HERE**} { \clist_use:Nn \l__wdsgn_notation_subscript_clist {,} }

  1. An empty field {}
  2. An empty constant \c_empty_tl, and
  3. No value token \c_novalue_tl (current implementation below)

and

  1. \tl_if_empty:nTF,
  2. \tl_if_blank:nTF, and
  3. \tl_if_eq:nnTF (current implementation below)

without success.

Here you find the minimal working example:

\documentclass{article}

\usepackage{amssymb, amsmath}
\usepackage{xparse}

\ExplSyntaxOn

\keys_define:nn { notation/nom }
 {
  A .tl_set:N = \l_wdsgn_notation_A_tl,
  B .tl_set:N = \l_wdsgn_notation_B_tl,
  C .tl_set:N = \l_wdsgn_notation_C_tl, 
  A .initial:n = {},
  B .initial:n = {},
  C .initial:n = {}, 
}

\NewDocumentCommand{\nom}{ m O{} }
 {
  \group_begin:
  \wdsgn_notation_nom:nn { #1 } { #2 }
  \group_end:
 }

\clist_new:N \l__wdsgn_notation_subscript_clist

\cs_new:Nn \wdsgn_notation_nom:nn
 {
  \keys_set:nn { notation/nom } { #2 }
% Gerneration of subscript list 
\clist_put_right:NV \l__wdsgn_notation_subscript_clist \l_wdsgn_notation_A_tl
\clist_put_right:NV \l__wdsgn_notation_subscript_clist \l_wdsgn_notation_B_tl
\amc{#1}
{
  \clist_if_empty:NTF \l__wdsgn_notation_subscript_clist {\c_novalue_tl} { \clist_use:Nn \l__wdsgn_notation_subscript_clist {,} }
}
{ % here we exploit the fact that \clist_use:Nn disregards empty items
 \clist_if_empty:NTF \l_wdsgn_notation_C_tl { \c_novalue_tl  } { \l_wdsgn_notation_C_tl }
}
}

\NewDocumentCommand \amc { m m m }
{
    (#1) -- 
    \tl_if_eq:nnTF {#2} {\c_novalue_tl} {empty} {not empty} -- 
    \tl_if_eq:nnTF {#3} {\c_novalue_tl} {empty} {not empty}
}

\ExplSyntaxOff

\begin{document}

\begin{align}
\nom{K}[A=A, B=B] \\
\nom{K}[A=A] \\
\nom{K}[B=B] \\
\nom{K}[C=guid]
\end{align}

\end{document}

As you can see empty is never printed when either #1 or #2 are empty.

Output:

enter image description here

Thanks in advance for the help.

4
  • 1
    Please note that \clist_use:Nn doesn't disregard empty elements, \clist_use:nn would.
    – Skillmon
    Commented Feb 29 at 9:33
  • 1
    Also please note that \clist_if_empty:NTF \l_wdsgn_notation_C_tl is wrong, that should be \tl_if_empty:NTF \l_wdsgn_notation_C_tl, and is unnecessary if you then check for emptiness in the next step again.
    – Skillmon
    Commented Feb 29 at 9:37
  • 1
    Another thing: Do you intend to use \amc on a document level? If not, I'd say you should also give it an L3 name and not define it with \NewDocumentCommand.
    – Skillmon
    Commented Feb 29 at 9:55
  • Comment 1: thanks to the hint. Comment 2: \clist_if_empty:NTF \l_wdsgn_notation_C_tl is wrong, that should be \tl_if_empty:NTF \l_wdsgn_notation_C_tl is actually another clist, in the real implementation i have at least 4 clists. I just wanted to simplify the problem. Comment 3: \nom is actually i use it to sort the inputed elements, \amc in this case is a place holder for another function that i call to generate some equations base of the inputs sorted and grouped by nom. This \amc command has at least 8 inputs.
    – wdsgn
    Commented Feb 29 at 10:31

2 Answers 2

5

If you use \tl_if_eq:nnTF {#1} { \c_novalue_tl } you're comparing these tokens exactly, so only a #1 that contains exactly \c_novalue_tl is true (so \tmp:n { \c_novalue_tl } with \tmp:n containing this check).

Your usage of \amc does not expand the arguments, so #2 will be

\clist_if_empty:NTF \l__wdsgn_notation_subscript_clist {\c_novalue_tl} { \clist_use:Nn \l__wdsgn_notation_subscript_clist {,} }

which is never \c_novalue_tl if you don't expand it with the correct number of expansion steps.

The following fixes this by expanding the first argument to \amc fully (\clist_use:Nn will prevent that the value is expanded too often), and for the second uses the value of your token list directly.

\documentclass{article}

\usepackage{amssymb, amsmath}
\usepackage{xparse}

\ExplSyntaxOn

\keys_define:nn { notation/nom }
 {
  A .tl_set:N = \l_wdsgn_notation_A_tl,
  B .tl_set:N = \l_wdsgn_notation_B_tl,
  C .tl_set:N = \l_wdsgn_notation_C_tl,
  A .initial:n = {},
  B .initial:n = {},
  C .initial:n = {},
}

\NewDocumentCommand{\nom}{ m O{} }
 {
  \group_begin:
  \wdsgn_notation_nom:nn { #1 } { #2 }
  \group_end:
 }

\clist_new:N \l__wdsgn_notation_subscript_clist

\exp_args_generate:n { neV }
\cs_new:Nn \wdsgn_notation_nom:nn
  {
    \keys_set:nn { notation/nom } { #2 }
    % Gerneration of subscript list
    \clist_put_right:NV \l__wdsgn_notation_subscript_clist \l_wdsgn_notation_A_tl
    \clist_put_right:NV \l__wdsgn_notation_subscript_clist \l_wdsgn_notation_B_tl
    \exp_args:NneV \amc{#1}
      {
        \clist_if_empty:NF \l__wdsgn_notation_subscript_clist { \clist_use:Nn \l__wdsgn_notation_subscript_clist {,} }
      }
      % here we exploit the fact that \clist_use:Nn disregards empty items
      \l_wdsgn_notation_C_tl
  }

\NewDocumentCommand \amc { m m m }
  {
    (#1) --
    \tl_if_empty:nTF {#2} {empty} {not empty} --
    \tl_if_empty:nTF {#3} {empty} {not empty}
  }

\ExplSyntaxOff

\begin{document}

\begin{align}
\nom{K}[A=A, B=B] \\
\nom{K}[A=A] \\
\nom{K}[B=B] \\
\nom{K}[C=guid]
\end{align}

\end{document}
2
  • Thanks for your initial reply, I see that i am mainly having a token expansion problem. I added you suggestions to my main code, however now I am having another issue: asume \amc is a command that receives 5 inputs, each of which is a token list generated using the method above, how do you suggest I modify lines \exp_args_generate:n { neV } and \exp_args:NneV ... to account for the extra arguments? The method above seems to work only for argument #2. Thanks in advance.
    – wdsgn
    Commented Feb 29 at 14:23
  • Easiest solution is \exp_last_unbraced:Ne \amc { { \clist_use:Nn ... } { \exp_not:V \l_your_variable_tl } { \exp_not:o { something-expanded-once } } ... }, in that case it doesn't matter how many argument's you're facing. But easier would be to define an L3 name for \amc and use something like \generate_variant:Nn \wdsgn_amc:nnnnn { eeeV }.
    – Skillmon
    Commented Feb 29 at 21:56
4

\c_novalue_tl is a very specific token list that cannot be used to test for emptiness.

You should expand the arguments before passing them to \amc (that I made an internal command, for this purpose).

\documentclass{article}

\usepackage{amssymb, amsmath}

\ExplSyntaxOn

\keys_define:nn { notation/nom }
 {
  A .tl_set:N = \l_wdsgn_notation_A_tl,
  B .tl_set:N = \l_wdsgn_notation_B_tl,
  C .tl_set:N = \l_wdsgn_notation_C_tl, 
  A .initial:n = {},
  B .initial:n = {},
  C .initial:n = {}, 
}

\NewDocumentCommand{\nom}{ m O{} }
 {
  \group_begin:
  \wdsgn_notation_nom:nn { #1 } { #2 }
  \group_end:
 }

\clist_new:N \l__wdsgn_notation_subscript_clist

\cs_new_protected:Nn \wdsgn_notation_nom:nn
 {
  \keys_set:nn { notation/nom } { #2 }
  % Gerneration of subscript list 
  \clist_put_right:NV \l__wdsgn_notation_subscript_clist \l_wdsgn_notation_A_tl
  \clist_put_right:NV \l__wdsgn_notation_subscript_clist \l_wdsgn_notation_B_tl
  \wdsgn_notation_amc:nee {#1}
   {
    \clist_if_empty:NTF \l__wdsgn_notation_subscript_clist
     {empty}
     { \clist_use:Nn \l__wdsgn_notation_subscript_clist {,} }
   }
   {
    \tl_if_empty:NTF \l_wdsgn_notation_C_tl { empty } { \l_wdsgn_notation_C_tl }
   }
 }

\cs_new:Nn \wdsgn_notation_amc:nnn
 {
    (#1) -- (#2) -- (#3)
 }
\cs_generate_variant:Nn \wdsgn_notation_amc:nnn { nee }

\ExplSyntaxOff

\begin{document}

\nom{K}[A=A, B=B]

\nom{K}[A=A]

\nom{K}[B=B]

\nom{K}[C=guid]

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .