5

Is it possible to change te outcome of a command depending on how many times it is called? I would like to have a command with 3 possible outcomes.

  1. Case 1: Outcome A in case it only occurs once in the document.
  2. Case 2: Outcome B for the first time it occurs in a document where it occurs multiple times and outcome C for the subsequent times it occurs in that document.

I would like not to use any arguments just the name of the command.

I know how to make the second case with a nested \newcommand. But does anyone know how to differentiate between case 1 and case 2? In other words, how can I make a command/function that has 3 different outcomes depending on how many times it is called?

  • I think this is something for a total counter? – user31729 Mar 11 '17 at 18:10
  • @Andrew In what context do you need this command? For something citation related? – user36296 Mar 11 '17 at 18:26
  • @samcarter: Yes, I use it for references. I need to reference some names. The first time I need to give the full name and the subsequent times just the abbreviation. So the first time the command outputs "the long reference (hereafter: the abbreviation)", the second time "the abbreviation". However, if the command is just used one, I would like it to just output the full reference instead of the full reference followed by the abbreviation as it would be superfluous. – Andrew Mar 11 '17 at 19:10
  • @Andrew: You should have really stated that this is about referencing stuff. Now my solution is pretty useless ... – user31729 Mar 11 '17 at 21:39
  • @ChristianHupfer: It is for referencing, but for the moment I don't use bib(la)tex. For the moment I am not using it because I don't have the necessary citation style (I cannot find it on line and I don't have time to make now one myself) for the 'real' references (so for the moment I am writing them myself and importing them from a central .csv). It is just for abbreviating names, not for referencing actual sources. It seems easier to stick with plain (La)TeX instead of adding bib(la)tex? – Andrew Mar 12 '17 at 0:33
5

You indicated in your comment, that you want to use this for citations. This makes the answer easy: use biblatex!

biblatex has all the necessary tests to deal with this situation:

\documentclass{article}
\usepackage[citecounter=true, style=authoryear, citetracker=true]{biblatex}
\usepackage{filecontents}

\begin{filecontents*}{\jobname.bib}
@article{duck,
  author    = {Duck, Donald},
  usera      = {Ducky},
  title     = {Bla},
  journal   = {Blub},
  year      = 2017
}

@article{mouse,
  author    = {Mouse, Minnie},
  usera      = {Mousy},
  title     = {Bla},
  journal   = {Blub},
  year      = 2017
}

\end{filecontents*}

\DeclareCiteCommand{\cite}
  {\usebibmacro{prenote}}%
  {\usebibmacro{citeindex}%
    \ifnum\thecitecounter=1
        \usebibmacro{cite}%
    \else%
         \ifciteseen{%
            \printfield{usera}%
         }{%
            \usebibmacro{cite}, in the following abbreviated as \printfield{usera}%
         }%
    \fi%
  }
  {\multicitedelim}
  {\usebibmacro{postnote}}

\addbibresource{\jobname.bib}

\begin{document}

    First citation: \cite{duck}

    Unique citation: \cite{mouse}

  Cite again: \cite{duck}

  \printbibliography
\end{document}

enter image description here

3

This applies a total document counter and associates it to a normal counter that counts the number of appearences of the \foo command with the features of xassoccnt.

The total number of appearences is saved at the end of the document and is available in the second run.

For more convenience, I've defined \fooonce, \foofirst and \foomorethanoncebutnotfirst macros for the output of the \foo command.

\documentclass{article}

\usepackage{xcolor}
\usepackage{xassoccnt}


\newcounter{occur}
\DeclareTotalAssociatedCounters{occur}{numofoccur}

\newcommand{\foosingle}{%
  \textcolor{red}{This is foo and it occurs only once!}%

}
\newcommand{\foofirst}{%
  \textcolor{blue}{This is foo, it appears more than once but this is the first time!}%

}

\newcommand{\foomorethanoncebutnotfirst}{%
  \textcolor{green}{This is foo and it appears multiple time, for example here, but it is not the first one!}

}

\newcommand{\foo}{%
  \refstepcounter{occur}%
  % Test for the total numbers first
  \ifnum\TotalValue{numofoccur}=1
  \foosingle%
  \else
  % Check for the current number of appearances...
  \ifnum\value{occur}=1 
  \foofirst%
  \else
  \foomorethanoncebutnotfirst%
  \fi
  \fi
}

\begin{document}

\foo

And 

\foo 

again.

\end{document}

If the second \foo is commented out, the output is

enter image description here

If the second \foo is kept inside, the output is

enter image description here

  • I am using datatool, but it seems like it prevents numofoccur from counting. Is there a possibility to prevent datatool from breaking this? Just loading datatool breaks it, I doesn't even need to call it. I call datatool like this: \usepackage[separator={;}]{datatool} \DTLloaddb[noheader,keys={key,reference}]{bibfile}{bronnen/bronnenlijst.csv} \newcommand{\cl}[1]{% \DTLfetch{bibfile}{key}{#1}{reference}% } – Andrew Mar 13 '17 at 16:04
  • @Andrew: I've have never used datatool so far and some files like bronnenlijst.csv are not accessible to me -- how should I test this? – user31729 Mar 13 '17 at 16:18
  • that's true, I was just wondering. I will continue searching. – Andrew Mar 13 '17 at 16:50
2

You can do it with the help of the .aux file:

\documentclass{article}

\makeatletter
\newcommand{\definename}[3]{%
  % #1 = macro name
  % #2 = name
  % #3 = abbreviation
  \newcommand#1{%
    \if\@usedonce{#1}#2\else#2~(#3)\fi
    \write\@auxout{\string\@isusedonce{\string#1}}%
    \gdef#1{%
      #3\write\@auxout{\string\@isusedtwice{\string#1}}%
      \gdef#1{#3}%
    }%
  }%
  \expandafter\newif\csname ifonce\string#1\endcsname
}
\def\@usedonce#1{TT\fi\csname ifonce\string#1\endcsname}
\def\@isusedonce#1{\global\csname once\string#1true\endcsname}
\def\@isusedtwice#1{\global\csname once\string#1false\endcsname}
\makeatother

\definename{\dickens}{Charles Dickens}{CD}
\definename{\adams}{Douglas Adams}{DA}

\begin{document}

Here I mention Dickens the first time: \dickens

Here I mention Dickens the second time: \dickens

Adams is mentioned just once: \adams

\end{document}

Note that you have to compile twice for the macros to align.

enter image description here

The first time \dickens appears, it writes about having been used once in the .aux file and redefines itself to just issue the abbreviation and to write in the .aux files about having been issued at least twice and redefines itself again to just print the abbreviation.

The \definename macro also sets up a conditional for each name; this conditional is set to true if an annotation in the .aux file says the macro is used at least once; it is set to false if the macro is used at least twice. When the “once” conditional returns true, just the name is printed the first (and unique) time; otherwise the name and abbreviation is printed. The redefinition of the macro follows.

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.