14

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}
  • 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. – jub0bs May 14 '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 '14 at 17:54
  • @zeroth: Thank you. Took me a bit of thinking, but finally I understood it. – celtschk May 14 '14 at 18:09
14

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

  • 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 '14 at 18:08
  • @celtschk Another strategy would be to use \@ifnextchar at the end of \myfirst. – egreg May 14 '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 '14 at 18:22
4

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}

  • 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 '14 at 18:04

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.