8

I'm curious to know how I would go about testing for macros by name. I need to do something that would be the logical equivalent of the following:

\def\doit#1{%
\if#1==\foo I got a foo\fi
\if#1==\bar I got a bar\fi
}

Now, of course I'm aware that \if doesn't work that way. The notation == isn't actually a thing, and the fact that \if expands macros is undesirable for my purposes, because I might want to do \doit\foo without \foo even being defined. However, I hope that the above pseudo-code serves to illustrate my question nonetheless.

I'm aware that there are better ways to pass named "flags" to a macro than as control sequences, but for reasons I won't go into here I really am constrained to macro names, and I really do need to be able to check if, given two macro tokens, their names are both the same.

Note that I'm using Plain TeX, and I'm seeking a solution that uses only TeX primitives and/or Plain TeX macros.

  • Will you always use it the way \doit\foo or would you want to also use it \doit{foo}? – Werner Apr 30 '14 at 5:23
  • Always \doit\foo. Of course that's a contrived example, but in my actual code the project is such that I have \doit\foo, and I need to distinguish between \foo and \bar, even when neither is defined. – patrick-rutkowski Apr 30 '14 at 6:05
  • Does Plain TeX know \pdfstrcmp? – Werner Apr 30 '14 at 6:24
  • @rutski OK, this is a string-like test. Do you need it to be expandable? If so, are there likely to be spaces in the names (under 'edge case' circumstances)? – Joseph Wright Apr 30 '14 at 6:25
  • @Werner Not a TeX90 or even e-TeX primitive. You can do an expandable string-based test using \if and some looping even without it: easier of course if the test does not need to be expandable. – Joseph Wright Apr 30 '14 at 6:26
6

If you don't need an expandable test, here's a possibility. I assume you have a finite set of flags.

% set the flags
\begingroup\escapechar=-1
\xdef\fooname{\string\foo}
\xdef\barname{\string\bar}
\endgroup

\def\nameequal#1#2{%
  TT\fi
  \begingroup
  \escapechar=-1
  \edef\nameequaltemp{\string#1}%
  \expandafter\endgroup
  \ifx\nameequaltemp#2}

\def\doit#1{%
  \if\nameequal#1\fooname
    I saw foo%
  \else
    \if\nameequal#1\barname
      I saw bar%
    \else
      I saw rubbish%
    \fi
  \fi
}

\doit\foo

\doit\bar

\doit\foobar

\bye

enter image description here

  • 1
    Why not just \edef\@tempa{\string#1}\edef\@tempb{\string#2}\ifx\@tempa\@tempb? – Joseph Wright Apr 30 '14 at 12:37
  • @JosephWright I like it better to declare the admissible flags beforehand. – egreg Apr 30 '14 at 15:32

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.