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.

TeX inserts \relax when it suddenly finds \else or \fi while expanding a conditional (eg, looking for a number). TeX by Topic says much. But how do you get rid of the \relax in a situation like the following fictitious example? eTeX's \dimexpr and \numexpr do vanish \relax but perhaps not in a situation like the following.

\edef\x{%
  \ifnum0=0\fi\ifnum\z@=\z@
    \expandafter\@firstoftwo\else
      \expandafter\@secondoftwo\fi{x}{y}%
} 

(Edited in from 'answer')

Martin, The \@empty may linger even in full expansion contexts: \noexpand makes expandable commands recoverable \relax. Moreover, at least 1/2 of the time one is not interested in full expansion or printing, but in a one- or two-step expansion. The outcome may even be immediately detokenized. So any extra \@empty or \space intended as an 'artificial' stopper will linger in the definition in situations where a non-expandable token is found before the artificial stopper. The following illustrates the point of Bruno, which I had been aware of:

\def\test@cond#1\fi{%
  #1\noexpand\@empty
    \expandafter\@firstoftwo\else
    \expandafter\@secondoftwo\fi{x}{y}%
}
\edef\x{\test@cond\ifnum\z@=\z@\fi}
\edef\x{\test@cond\if xx\fi}
\edef\x{\test@cond\ifnum0=0\fi}

I have found a tricky solution involving \iffirstisspace macro, and \romannumeral too offers a way out.

share|improve this question
1  
Could you please explain what you mean by "TeX by Topic says much"? –  Hendrik Vogt Mar 25 '11 at 15:46
    
When you are at this levet, the comp.text.tex news groups might be a better place to ask –  daleif Mar 25 '11 at 15:55
    
@Hendrik Vogt: When I looked in TeX by Topic I saw where it mentions that TeX does itself insert \relax in some circumstances, but it says nothing about how to get rid of the \relax in an \edef context. Then I saw somewhere in an issue of TUGBoat that \dimexpr and \numexpr do remove \relax after evaluating the dimension or number. That is indeed true, but they fail in the above example. –  Ahmed Musa Mar 25 '11 at 16:05
    
@Ahmed: Maybe you could give a precise reference where this is written in TeX by Topic? –  Hendrik Vogt Mar 25 '11 at 16:14
    
@Hendrik Vogt: TeX by Topic, Section 12.5.3, page 104 (2001 edition). –  Ahmed Musa Mar 25 '11 at 16:41
show 1 more comment

1 Answer

TeX stops looking for a number e.g. when it finds a space which is then consumed. Therefore your example could be fixed like this:

\edef\x{%
  \ifnum0=0 \fi\ifnum\z@=\z@
    \expandafter\@firstoftwo\else
      \expandafter\@secondoftwo\fi{x}{y}%
} 

However, in the general case it might not be so easy:

\edef\x{%
  \ifnum\macroa=\macrob \fi\ifnum\z@=\z@
    \expandafter\@firstoftwo\else
      \expandafter\@secondoftwo\fi{x}{y}%
} 

If \macrob doesn't end with a space the relax is still inserted. Adding a normal space after it is of course removed like any other space after command sequences. Adding an explicit \space would work as long \macrob doesn't end with one, otherwise it will not be removed and be part of the definition.

Here helps eTeX with \numexpr which can be used with \relax as an end-marker:

\edef\x{%
  \ifnum\macroa=\numexpr\macrob\relax\fi\ifnum\z@=\z@
    \expandafter\@firstoftwo\else
      \expandafter\@secondoftwo\fi{x}{y}%
} 

Then \macrob works independent if it contains a trailing space or not.

So I think the answer to your question "How to vanish \relax inserted by TeX itself" is: don't let TeX insert one in the first place by avoiding the situation.

share|improve this answer
    
Thank you for the contribution. I already knew about the space stopper and much of what you have said. Don't allow TeX to insert \relax: good! But sometimes you want to cnstruct a general macro to test all types of conditions, including explicit numbers (that are not macros, \dimendef'd, \countdef'd or \skipdefd). –  Ahmed Musa Mar 25 '11 at 16:36
2  
@Ahmed: I thought that you knew most of the things I stated. I added it so that others can follow. Just had this idea: \ifnum0=0\noexpand\empty\fi which works for avoiding the implicit \relax. –  Martin Scharrer Mar 25 '11 at 16:44
1  
Clever idea of using \noexpand\empty! –  TH. Mar 25 '11 at 20:24
    
But it would not work if you replace the second 0 by 0\space (perhaps hidden in a macro). –  Bruno Le Floch Mar 25 '11 at 21:49
    
@Bruno: Yes, than \x would contain \empty but it would still be fully expandable. –  Martin Scharrer Mar 25 '11 at 22:03
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.