5

Based on this question, I'd like the following

\newcommand{\word}{Paul}
\newcommand{\butnot}{Joe}
\IfStringInList{\word}{George,John,Paul,Ringo}{Beat it}{Roll it}
\IfStringInList{\butnot}{George,John,Paul,Ringo}{Beat it}{Roll it}

to return Beat it and Roll it.

This has in principle been answered here but only with the help of 2 packages. It should, however, be possible much simpler with the solution here, only that I couldn't figure out how to expand the macro? (Not even with the help of this reference :/ )

2 Answers 2

3

Like this? You need to make sure that \word and/or \butnot get expanded first. This can also be achieved with some \expandafters but since I am never sure how many of those one needs I use a more mundane but IMHO also more accessible syntax. Of course there are many tools that help you doing the same (but at the very moment of writing this I am fighting a conflict between \tikzexternalize and xparse so I feel this solution might be useful for some who have similar clashes).

\documentclass{article}

\makeatletter
\newcommand*{\IfStringInList}[2]{%
  \in@{,#1,}{,#2,}%
  \ifin@
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\makeatother
\newcommand{\IfStringInListExpandedDo}[4]{%
\edef\tmp{\noexpand\IfStringInList{#1}{#2}{\noexpand\edef\noexpand\tst{1}}{\noexpand\edef\noexpand\tst{0}}}%
\tmp%
\ifnum\tst=1\relax%
#3%
\else%
#4%
\fi}

\begin{document}
\newcommand{\word}{Paul}
\newcommand{\butnot}{Joe}
\IfStringInListExpandedDo{\word}{George,John,Paul,Ringo}{abc \textbf{Beat it}}{cde \textit{Roll it}}
\IfStringInListExpandedDo{\butnot}{George,John,Paul,Ringo}{abc\textbf{Beat it}}{cde \textit{Roll it}}
\end{document}

enter image description here

9
  • Yes, exactly. I had tried \edef without success. How does that work? What is \tmp needed for? Commented May 7, 2019 at 8:16
  • Hm, this fails if there are macros (e.g. \textbf) in Beat it :( Commented May 7, 2019 at 8:31
  • @fuenfundachtzig This tells LaTeX to first expand \word (or \butnot) and then \IfStringInList. And no, \textbf and so on do not work in this version (but I didn't know that was a requirement).
    – user121799
    Commented May 7, 2019 at 13:49
  • Thanks. Not it wasn't an explicit requirement. But is it possible to make this work? Commented May 7, 2019 at 16:35
  • @fuenfundachtzig Yes, sure. \edef\tmp{\noexpand\IfStringInList{\word}{George,John,Paul,Ringo}{\noexpand\textbf{Beat it}}{Roll it} \noexpand\IfStringInList{\butnot}{George,John,Paul,Ringo}{\noexpand\textbf{Beat it}}{Roll it}}% \tmp You need to make sure that these get expanded only in the very end, when \IfStringInList gets expanded.
    – user121799
    Commented May 7, 2019 at 16:39
5

Essentially a one liner with expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\IfStringInList}{mmmm}
 {
  \clist_if_in:neTF {#2} {#1} {#3} {#4}
 }
\prg_generate_conditional_variant:Nnn \clist_if_in:nn {ne} {T,F,TF}
\ExplSyntaxOff

\begin{document}

\newcommand{\word}{Paul}
\newcommand{\butnot}{Joe}

\IfStringInList{\word}{George,John,Paul,Ringo}{Beat it}{Roll it}

\IfStringInList{\butnot}{George,John,Paul,Ringo}{Beat it}{Roll it}

\end{document}

With e we force full expansion of the first argument.

enter image description here

By the way, e expansion is a big achievement in TeX Live 2019, available with all TeX engines. Since you're talking of strings, I suppose that the material in the search string is fully expandable to characters.

2
  • Oooh, e-type expansion!
    – Joseph Wright
    Commented May 6, 2019 at 21:27
  • @JosephWright I like to be modern. ;-)
    – egreg
    Commented May 6, 2019 at 21:28

You must log in to answer this question.

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