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.

I've written the following code:

\newif\ifconsecutive
\consecutivefalse

\newcommand{\myfirst}[1]{#1\consecutivetrue\expandafter\consecutivefalse}
\newcommand{\mysecond}[1]{\ifconsecutive $\longrightarrow$\fi #1}

The idea was that if I write

\myfirst{A}\mysecond{B}

I get the equivalent of

A $\longrightarrow$ B

while if I type something in between, like

\myfirst{A} then \mysecond{B}

I instead get the equivalent of

A then B

The idea was that \expandafter would cause the text following the invocation of \myfirst (either an invocation of \mysecond or some arbitrary other code) to be expanded while \consecutivetrue is in effect, so if the next thing is a \mysecond invocation, the \ifconsecutive will be executed and the arrow generated, while if something else follows, it will not care about \consecutivetrue. After that expansion, \consecutivefalse should be called, causing any later invocation of \mysecond to not generate the arrow.

However what actually happens is that the arrow never gets inserted, no matter whether the macros are consecutive or not.

Now my question is: Why does this pair of macros not work as intended?

Here's a complete compilable code:

\documentclass{article}

\newif\ifconsecutive
\consecutivefalse
\newcommand{\myfirst}[1]{#1\consecutivetrue\expandafter\consecutivefalse}
\newcommand{\mysecond}[1]{\ifconsecutive $_$\fi #1}

\begin{document}
\myfirst{A}\mysecond{B}

\myfirst{A} then \mysecond{B}
\end{document}
share|improve this question
    
Please make your code compilable (if possible), or at least complete it with \documentclass{...}, the required \usepackage's, \begin{document}, and \end{document}. That may seem tedious to you, but think of the extra work it represents for TeX.SX users willing to give you a hand. Help them help you: remove that one hurdle between you and a solution to your problem. –  Jubobs May 14 at 17:52
    
Expandafter doesn't fully expand the next token, only once. Hence, it expands \mysecond, executes \consecutivefalse and then continues with the expanded \mysecond. See this post for tracking/tracing LaTeX: tex.stackexchange.com/questions/538/how-to-best-debug-latex –  zeroth May 14 at 17:54
    
@zeroth: Thank you. Took me a bit of thinking, but finally I understood it. –  celtschk May 14 at 18:09

2 Answers 2

up vote 14 down vote accepted

You don't want to just expand \mysecond, but also the \ifconsecutive that results, so you need three \expandafter tokens in front of \consecutivefalse.

\documentclass{article}

\newif\ifconsecutive
\consecutivefalse
\newcommand{\myfirst}[1]{#1\consecutivetrue\expandafter\expandafter\expandafter\consecutivefalse}
\newcommand{\mysecond}[1]{\ifconsecutive ${}\to\nobreak{}$\fi #1}

\begin{document}
\myfirst{A}\mysecond{B}

\myfirst{A} then \mysecond{B}
\end{document}

enter image description here

However, I wouldn't recommend such context sensitive macros.

A different strategy is with \new@ifnextchar, the version of \@ifnextchar provided by amsmath that doesn't gobble or ignore spaces:

\documentclass{article}
\usepackage{amsmath}

\makeatletter
\newcommand{\myfirst}[1]{#1\new@ifnextchar\mysecond{${}\to\nobreak{}$}{}}
\newcommand{\mysecond}[1]{#1}

\begin{document}
\myfirst{A}\mysecond{B}

\myfirst{A} \mysecond{B}

\myfirst{A} then \mysecond{B}

\myfirst{A}\relax\mysecond{B}
\end{document}

enter image description here

share|improve this answer
    
Thank you (and also zeroth in the comments). I guess I was thinking too much in terms of macro "execution" instead of expansion. –  celtschk May 14 at 18:08
    
@celtschk Another strategy would be to use \@ifnextchar at the end of \myfirst. –  egreg May 14 at 18:11
    
Interesting, I didn't know about that macro. It differs from the other solution in that following whitespace is ignored (which I consider reasonable). –  celtschk May 14 at 18:22

An alternative:

\documentclass{article}
\newcommand\mycmd[3][$\longrightarrow$]{#2 #1 #3}
\begin{document}    
\mycmd{A}{B}

\mycmd[then]{A}{B}

\end{document}

It is also possible to define the command as \mycmd{A}[then]{B}

share|improve this answer
    
Thanks, but that doesn't answer my question. Indeed, an even simpler alternative to my example would have been to just write A $\longrightarrow$ B and A then B. But that certainly does not help understanding anything ... –  celtschk May 14 at 18:04

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.