I am using \str_if_eq:xxTF{\A}{\Target}{<true>}{<false} to execute the <true> or <false> code if \A=\Target.

What is the list version equivalent of this?

So I am looking for something such as


which executes the appropriate <true>/<false> if A is in the list (CSV) \TargetList?

I have to admit I have not tried for too long on this as I really can't read expl3 syntax yet, but a few of the macros presented at Using Expl3 token-list variables where token lists are called for looked interesting, but I was not able to get them to work.

So, in the MWE below, by changing \GetTexFilePath and \GetTexFilePathExpandable the last three lines should not have an xxx in the directory path. The current output is:

enter image description here


  • The \TargetList is always a macro that contains the list.
  • The source of the comparison is usually a value declared with \newtoks as per the MWE below (not sure if that matters).


Before people get the wrong idea and think that I actually understand some expl3 syntax, here is where that code originated from:

Possible clue to solution:




%% These directories should never have an "xxx" in the path.
%% The values here do NOT change at run time.
%% https://tex.stackexchange.com/questions/46323/how-to-expand-values-stored-in-a-token-defined-by-newtoks

%% The list of members here do NOT change at run time.
    \SpecialDirectoryC,% <-- would prefer to be allowed extra comma here, but
                       %     can do without that if it adds too much complexity


\ExplSyntaxOn%%% These work fine...
% Determine path: Always #1/xxx#2/#3 unless #1=\SpecialDirectory
\NewDocumentCommand{\GetTexFilePathOld}{m m m}{%

\DeclareExpandableDocumentCommand{\GetTexFilePathExpandableOld}{m m m}{%

%%% how do I define these ...
% Determine path: Always #1/xxx#2/#3 unless #1 is in \ListOfSpecialDirectories

% Don't work: % \tl_if_in:nnTF  \str_if_in:nnTF,  \str_if_in:xxTF
\NewDocumentCommand{\GetTexFilePath}{m m m}{%

\DeclareExpandableDocumentCommand{\GetTexFilePathExpandable}{m m m}{%

\noindent\textbf{These work fine:}

Should have xxx in path: 

\medskip\par Should \emph{not} have xxx: 

\noindent\textbf{Paths starting with AAA, BBB, or CCC should not have an xxxx in the path}

Should have xxx in path: 

\medskip\par Should \emph{not} have xxx: 

\medskip\par Should \emph{not} have xxx: 

\medskip\par Should \emph{not} have xxx: 
  • No function with x in the argument specifiers is fully expandable; you probably are thinking to \str_if_eq_x:nnTF
    – egreg
    Feb 23, 2013 at 20:13
  • @egreg: So does that just mean the function is misnamed \GetTexFilePathExpandable, or is there really no difference in those two function. I don't recall why, but there was a case where I needed to use \DeclareExpandableDocumentCommand instead of \NewDocumentCommand to get things to work. Perhaps that was before I changed to using \str_if_eq. Would be happy to eliminate redundant code if those two are identical. Feb 23, 2013 at 20:17
  • It depends in what context you need those macros; but they are just the same (apart from minor details).
    – egreg
    Feb 23, 2013 at 20:18
  • @egreg: Re your first comment: Using \str_if_eq_x:nnTF in \GetTexFilePathOld or \GetTexFilePathExpandable breaks things as is the case with this MWE. Re your second comment: I am using these macros to determine where appropriate files should be, test to see if they exist, add links to them, and perhaps even \include them (after similarly generating the appropriate file name and adding an extension based on the context. Feb 23, 2013 at 20:25
  • I have two questions: 1) is the first argument to \GetTexFilePath always going to be a macro? 2) Do you want to detect the macro names that contain the directories (i.e. \SpecialDirectory) or their expansion (i.e. AAA)?
    – cgnieder
    Feb 23, 2013 at 20:29

1 Answer 1


I don't know if this really answers your needs, which I can't understand precisely.

\NewDocumentCommand{\GetTeXFilePath}{m m m}
  \grill_str_if_eq_x_in:nVTF { #1 } \ListOfSpecialDirectories {#1/#2/#3} {#1/xxx#2/#3}

\bool_new:N \l__grill_path_bool
\prg_new_protected_conditional:Npnn \grill_str_if_eq_x_in:nn #1 #2 { T,F,TF }
  \bool_set_false:N \l__grill_path_bool
  \clist_map_inline:nn { #2 }
    \str_if_eq_x:nnT { #1 } { ##1 }
     { \clist_map_break:n { \bool_set_true:N \l__grill_path_bool } }
   \bool_if:NTF \l__grill_path_bool
    { \prg_return_true: }
    { \prg_return_false: }
\cs_generate_variant:Nn \grill_str_if_eq_x_in:nnTF { nV }


\newcommand{\ListOfSpecialDirectories}{\SpecialDirectory, \SpecialDirectoryB, \SpecialDirectoryC}




This will print


but of course this can't be used in an expandable context. However, if you want to use the result, just say

\NewDocumentCommand{\GetTeXFilePath}{m m m}
  \grill_str_if_eq_x_in:nVTF { #1 } \ListOfSpecialDirectories
    { \tl_set:Nn \l_grill_result_tl {#1/#2/#3} }
    { \tl_set:Nn \l_grill_result_tl {#1/xxx#2/#3} }

and use \l_grill_result_tl for passing it to some other macro.

  • This seems to work for at least the my use case. I did notice that it failed with \protected\def\SpecialDirectory{AAA} and \GetTeXFilePath{AAA}{2012}{05}, but I won't be using it like that. I use it as \GetTeXFilePath{\SpecialDirectory}{2012}{05} which works fine. Adapting now fo my actual usage... Feb 23, 2013 at 20:51
  • Yes, \protected inhibits expansion in \edef and this is something you don't want in this case.
    – egreg
    Feb 23, 2013 at 20:53
  • I needed to use \protect based on How to expand values stored in a token defined by newtoks. So, just to clarify, using it as \protected\def\SpecialDirectory{AAA} and \GetTeXFilePath{\SpecialDirectory}{2012}{05} should not cause any issues, as it does work indeed appear to work in the MWE. Feb 23, 2013 at 20:56
  • @PeterGrill This is because I used \str_if_eq_x:nnT; it wouldn't with \str_if_eq:xxT
    – egreg
    Feb 23, 2013 at 21:06
  • @PeterGrill Sorry, \tl_set:Nn
    – egreg
    Feb 23, 2013 at 21:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.