Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

In a bigger context, I need to check whether an integer parameter is contained in a set of numbers. I decided to encode sets as strings; elements are separated by !. I don't know whether this is the best way to do this, but a curious thing happens:

\documentclass{article}
\usepackage{pgffor,xifthen}

\newcommand{\ifin}[1]{
  \ifthenelse{\isin{!#1!}{!1!3!}}{T}{F}%
}

\begin{document}
\ifin{1}\ifin{2}\ifin{3}\ifin{4}

\foreach \n in {1,...,4} {%
  \ifin{\n}%
}
\end{document}

The expected output is

TFTF
TFTF

but the actual output is

TFTF
FFFF

Note that pdflatex does not report any errors or warnings.

I suspect that this is a more general issue (\isin checks whether strings are substrings of other strings; it probably fails because the parameter is a number) but I can not find material on this. How can I achieve the desired behaviour?

share|improve this question
    
I have been searching for the wrong keywords, probably. Apologies if the question is trivial. –  Raphael May 17 '12 at 13:56
    
Use: \foreach \n in {1,...,4} {% \edef\x{\noexpand\ifin{\n}}\x } –  Marco Daniel May 17 '12 at 14:11
1  
or simpler ` \expandafter\ifin\expandafter{\n}%` –  David Carlisle May 17 '12 at 14:14
    
@Raphael: This is just a warning, before you ask later - as many have done previously. If you're printing the result of your test, you should have no problem with \foreach. But if you do any assignment in the scope of \foreach, it will be local to that scope/group, and you won't find it outside that scope unless you prefix the assignment with \global. Moreover, I hope your example is actually a MWE, since it doesn't make much sense to me. –  Ahmed Musa May 17 '12 at 15:01
    
@AhmedMusa: Thanks for the warning. It is an M(N)WE; check the linked question for my use case. –  Raphael May 17 '12 at 15:08
add comment

1 Answer

up vote 6 down vote accepted

This is an expansion issue: the token \n is not in your list, as you will agree.

You have to communicate explicitly that you want to check for the value of \n rather than the name \n:

\foreach \n in {1,...,4} {%
  \expandafter\ifin\expandafter{\n}%
}

An alternative is to use \edef (like \edef\temp{\noexpand\ifin{\n}}\temp).

See http://pgfplots.sourceforge.net/TeX-programming-notes.pdf for details on expansion control.

NOTE: I would not be surprised if commands like \if* cause trouble if they are used deep inside of some macro. This is caused by TeX's tokenizer; the name interferes with the way TeX handles boolean variables. I would suggest a different prefix (say, \raphaelifin).

share|improve this answer
1  
actually \ifin isn't an if in the sense of \newif so it's just as safe as \raphaelifin to TeX (although confusing toi humans as it looks like an if. –  David Carlisle May 17 '12 at 14:16
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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