How to convert macro output to string
True, \foo
is not expanded and therefore doesn't seem like a CSV within \ifmember
. We can expand both arguments to ensure you're working with a full list:
True
True
False
True
True
\documentclass{article}
\makeatletter
\newcommand\ifmember[2]{%
\begingroup
\edef\x{\endgroup\noexpand\in@{,#1,}{,#2,}}\x%
\ifin@
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother
\begin{document}
\ifmember{3}{3,4}{True}{False}
\newcommand{\foo}{3,4}%
\ifmember{3}{\foo}{True}{False}
\ifmember{44}{\foo}{True}{False}
\ifmember{\foo}{\foo}{True}{False}
\newcommand{\baz}{4}%
\ifmember{\baz}{\foo}{True}{False}
\end{document}
No need to reinvent the wheel. ;-)
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\ifmember}{mmmm}
{
\clist_if_in:onTF { #2 } { #1 } { #3 } { #4 }
}
\cs_generate_variant:Nn \clist_if_in:nnTF { o }
\ExplSyntaxOff
\begin{document}
\ifmember{3}{3,4}{True}{False} (expected: True)
\ifmember{3}{ 3 ,4}{True}{False} (expected: True)
\newcommand{\foo}{3,4}
\ifmember{3}{\foo}{True}{False} (expected: True)
\renewcommand{\foo}{3, 4}
\ifmember{4}{\foo}{True}{False} (expected: True)
\ifmember{foo}{\foo}{True}{False} (expected: False)
\end{document}
\clist_if_in:<args>
has the comma separated list in the first argument, the item to look for in the second one.
To be honest, I'd better split the check into two variants: one for a “naked” argument, one for a control sequence:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\ifmember}{smmmm}
{
\IfBooleanTF{#1}
{% explicit argument
\clist_if_in:nnTF { #3 } { #2 } { #4 } { #5 }
}
{% implicit argument
\clist_if_in:VnTF #3 { #2 } { #4 } { #5 }
}
}
\cs_generate_variant:Nn \clist_if_in:nnTF { V }
\ExplSyntaxOff
\begin{document}
\ifmember*{3}{3,4}{True}{False} (expected: True)
\ifmember*{3}{ 3 ,4}{True}{False} (expected: True)
\newcommand{\foo}{3,4}
\ifmember{3}{\foo}{True}{False} (expected: True)
\renewcommand{\foo}{3, 4}
\ifmember{4}{\foo}{True}{False} (expected: True)
\ifmember{foo}{\foo}{True}{False} (expected: False)
\end{document}
Anyway, here's a solution for your code: reverse the arguments, so you can easily reach the second with \expandafter
.
\documentclass[11pt,letterpaper]{article}
\makeatletter
\newcommand\ifmember[2]{%
\expandafter\ifmember@aux\expandafter{#2}{#1}%
}
\newcommand\ifmember@aux[2]{%
\in@{,#2,}{,#1,}%
\ifin@
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother
\begin{document}
\ifmember{3}{3,4}{True}{False}
\newcommand{\foo}{3,4}
\ifmember{3}{\foo}{True}{False}
\end{document}
As you mentioned that you tried with \expandafter
, I provide an example exhibiting how first-level-expansion of \foo
could be accomplished using \expandafter
.
Nonetheless I definitely prefer Werner's answer and egreg's answer to what I am about to provide.
\documentclass[11pt,letterpaper]{article}
\makeatletter
\newcommand\ifmember[2]{%
\in@{,#1,}{,#2,}%
\ifin@
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}%
\makeatother
\newcommand\ExpandSecondArgumentOnceFirst[2]{%
\expandafter\PassFirstArgumentToSecondArgument\expandafter{#2}{#1}%
}%
\newcommand\PassFirstArgumentToSecondArgument[2]{#2{#1}}%
\begin{document}
\ifmember{3}{3,4}{True}{False}
\newcommand\foo{3,4}
\ExpandSecondArgumentOnceFirst{\ifmember{3}}{\foo}{True}{False}
% or:
\expandafter\PassFirstArgumentToSecondArgument\expandafter{\foo}{\ifmember{3}}{True}{False}
\end{document}
The gist of the trick is having TeX flip around macro arguments in order to temporarily have the second argument available as first argument and thus knowing exactly about the amount of \expandafter
needed for "reaching" it.
Of course this trick can only be applied successfully in those special cases where first-level-expansion of \ifmember
's second argument's first token yields fully expanded the entire list and not something like \barA,\barB
which would be the case with:
\def\barA{3}
\def\barB{4}
\def\foo{\barA,\barB}
In the latter case first-level-expanding \foo
yields: \barA,\barB
and not 3,4
while Werner's \edef
-approach does not just first-level-expansion but does expand completely until there are no more expandable tokens and thus even in the latter case (and the like situations) yields 3,4
.
That's why I prefer Werner's answer and why my answer should not be taken for something suitable for all-day-usage but should be taken for a moot point showing how the trick could be done using \expandafter
in your special case of first-level-expanding \foo
already yielding the fully expanded list.