5

I want to create a command that changes its output the second time it gets called. For example, I want it to yield 1 the first time it's called, and 2 the second time:

\newcommand\mycommand { do stuff }
\mycommand % yields 1
\mycommand % yields 2

My idea was to define a global variable, something like \hasbeencalled, and globally redefine that variable if the command has been called. Something like:

\def\hasbeencalled{0}
\newcommand\mycommand[1] {
    \ifnum\hasbeencalled=0
        1
        \global\def\hasbeencalled{1}
    \else
         2
    \fi
}

But this doesn't work. Somehow the global redefinition happens retroactively and changes it so that I get the output

\mycommand % yields 2
\mycommand % yields 2

But if I take away the \global, then I get

\mycommand % yields 1
\mycommand % yields 1

What can I do?

3 Answers 3

10

enter image description here

as plain tex but works in latex as well:

\def\mycommand{1\gdef\mycommand{2}}

\mycommand

\mycommand

\mycommand

\bye
3
  • \bye in LaTeX?
    – cfr
    Jan 15, 2016 at 2:05
  • @cfr as it says in what I wrote, the example is plain tex, but the definition would work in latex. Jan 15, 2016 at 7:49
  • All I meant was that somebody who doesn't know much about TeX/LaTeX is likely to copy paste all of the code and not realise they should just use the relevant bit. But maybe I'm wrong about that.
    – cfr
    Jan 15, 2016 at 20:23
5

You can just set a "toggle", which starts out as being false, and is set to true once you've received the special input.

Below I've made an \if that represents this toggle:

enter image description here

\documentclass{article}

\makeatletter
\newif\if@mycommand@special
\newcommand\mycommand[1]{%
  \ifnum\pdfstrcmp{#1}{7}=0 % Compare argument to "7" (or something special)
    \if@mycommand@special
      #1 (subsequent call)%
    \else
      #1 (first call)%
    \fi
    \global\@mycommand@specialtrue% "7" has been used...
  \else
    #1% Do something else
  \fi
}
\makeatother

\begin{document}

\setlength{\parindent}{0pt}% Just for this example
\mycommand{1}

\mycommand{2}

\mycommand{1}

\mycommand{7}

\mycommand{9}

\mycommand{7}

\mycommand{9}

\mycommand{7}

\end{document}

Comparison is done using e-TeX's \pdfstrcmp{<strA>}{<strB>}, which performs a string comparison. The result is 0 if the <strA> = <strB>.

5
  • Thanks for your quick reply. I don't know why, but this isn't working where I'm applying it. I'm trying to use it inside of a tikz plot, and I get "subsequent call" all times :\ Jan 14, 2016 at 1:43
  • 1
    @rhombidodecahedron: The usage of this within some other context surely makes for a complication. Could you please add these details to your question so we can replicate your problem?
    – Werner
    Jan 14, 2016 at 1:47
  • 1
    @rhombidodecahedron If you mean pgfplots by TikZ yes it won't work. You have to expand the macro immeadiately before the axis environment is finished.
    – percusse
    Jan 14, 2016 at 5:57
  • @percusse how can I do that? Jan 14, 2016 at 17:38
  • @rhombidodecahedron: Please show us a use-case.
    – Werner
    Jan 14, 2016 at 19:26
3

This might be a simple typing error. In your \ifnum you use \hasbeenseen but everywhere else it's \hasbeencalled. If you change it you get a working

\documentclass{article}

\begin{document}

\def\hasbeencalled{0}
\newcommand\mycommand[1] {
    \ifnum\hasbeencalled=0
        1
        \global\def\hasbeencalled{1}
    \else
         2
    \fi
}

\mycommand{}
\mycommand{}

\end{document}

Please note that you define \mycommand with an mandatory argument (which you don't use) so you should call it

\mycommand{}
\mycommand{}

giving empty arguments. A simple

\mycommand
\mycommand

will result in plugging the second \mycommand as argument for the first one and thus only showing one number.

3
  • And you get so many spaces… ;-)
    – egreg
    Jan 14, 2016 at 9:20
  • @egreg: I suspected, Werner had only presented us a reduced version and his real-world use actually uses this argument, so I didn't change the definition. Jan 14, 2016 at 12:11
  • I think @egreg means the other spaces, but I could be mistaken.
    – cfr
    Jan 15, 2016 at 2:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .