8

I need a command to behave differently the first time than the next times it's called. Right now I use \newcommand\foo{First\gdef\foo{Next}}, that is, it redefines itself the first time.

Moreover, I need to “reset” its meaning at some point, so I define \newcommand\resetfoo{\gdef\foo{First\gdef\foo{Next}}}.

But this seems to me rather difficult. May be there is an usual way of doing this, but I'm not aware of it (also, I know almost nothing about expansion). Which is the correct way of solving this kind of problem?

Question

As the question states, I need a more general way: some function to change its definition in its n th “expansion” (I'm not sure I'm using the word in the right place). How would you solve this problem? I also need the necessary \resetfoo.

In case it's not already done in some way, my idea is to have some command \changedefinitionafter\foo{3}{OneTwoThree}{Next} or something like that. expl3 solution is also welcome.

Here is a more general MWE.

\documentclass{scrartcl}

\newcommand\foo{First\gdef\foo{Next}}
\newcommand\resetfoo{\gdef\foo{First\gdef\foo{Next}}}

\begin{document}

\foo~\foo~\foo
\resetfoo~\foo~\foo

\end{document}

Also, tags and suggestions for the title of the question are welcome.

2
  • 7
    I'd define a counter which is increased every time the command is used. In the definition of the command you can then switch the meaning if you check the value of the counter before. Mar 17 '14 at 12:48
  • That's an approach I didn't think of. I'm still not pleased with the idea that the command “carries” all that checking with him, so I will probably make it just redefine itself when the counter reaches some value.
    – Manuel
    Mar 17 '14 at 14:24
13

Have a look at the following example:

\documentclass{article}

\newcounter{testcount}

\newcommand{\modifyme}{%
\addtocounter{testcount}{1}
\ifnum\thetestcount<3%
    Hello 
\fi
\ifnum\thetestcount>2%
    World
\fi
}

\newcommand{\resetme}{\setcounter{testcount}{0}}

\begin{document}

\modifyme

\modifyme

\modifyme

\modifyme

\resetme

\modifyme

\end{document}

Updated example

2
  • Could you add the \resetfoo to answer the question? I guess it's only a \setcounter{…}{0} but the idea is that future readers find it. I'm going to accept this answer.
    – Manuel
    Mar 17 '14 at 17:56
  • I just added the \resetme command. Mar 17 '14 at 18:41
9

I love using counters! Here only the expansion after the number specified in \changedefinitionafter is modified.

\documentclass{article}
\pagestyle{empty}% for cropping
\makeatletter
\newcount\count@foo
\newcount\nth@foo
\newcommand\changedefinitionafter[4]{
    % #1: name of macro
    % #2: exceptional occurence
    % #3: normal expansion
    % #4: exceptional expansion
    \global\count@foo=0
    \global\nth@foo=#2
    \gdef#1{%
        \advance\count@foo by 1
        \ifnum\count@foo=\nth@foo
            #4%
        \else
            #3%
        \fi
    }
    \edef\resetname{reset\expandafter\@gobble\string#1}
    \expandafter\gdef\csname \resetname \endcsname{\global\count@foo=0 }
}
\makeatother
\begin{document}
\obeylines
\changedefinitionafter\foo{3}{OneTwoThree}{Next}
\foo
\foo
\foo
\foo
\resetfoo
\foo
\foo
\foo
\foo
\end{document}

enter image description here

6

No counter, but three macros for each command of this type:

\documentclass{article}

\makeatletter
\newcommand{\newchangingcommand}[4]{%
  % #1 = macro name
  % #2 = steps
  % #3 = value until step #1
  % #4 = value from step #1
  \@namedef{\string#1@counter}{0}%
  \@namedef{\string#1@limit}{#2}%
  \def#1{%
     % step the counter
     \global\@nameedef{\string#1@counter}{\number\numexpr\@nameuse{\string#1@counter}+1\relax}%
     \ifnum\@nameuse{\string#1@counter}=\@nameuse{\string#1@limit}\relax
       \gdef#1{#4}#4%
     \else
       #3%
     \fi
  }%
}
\providecommand\@nameedef[1]{\expandafter\edef\csname#1\endcsname}
\makeatother

\newchangingcommand{\foo}{3}{Two}{Next}
\newchangingcommand{\foob}{2}{One}{Next}

\begin{document}

\foo--\foob\par
\foo--\foob\par
\foo--\foob\par
\foo--\foob\par

\end{document}

enter image description here

Be aware that using such commands in moving arguments will fail for several reasons.

1
  • 1
    Is there any clear benefit in this system versus the “counters system”?
    – Manuel
    Mar 17 '14 at 14:38

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.