7

In order to complete one custom package command I needed an internal macro, I called it \@test@count{❬argument❭}, and should accomplish the following:

  1. Internally defines a new counter \❬argument❭ and sets it to 1.
  2. Checks if the counter \❬argument❭ is already defined, so it has to be conditionally dependent of the existence of previous counters:

    2.1. If \❬argument❭ is already defined, then it'll not overwrite a previous value stored by \❬argument❭ (as if it has saved its declaration) but it will advance it by 1.

    2.2. If \❬argument❭ isn't defined, then it'll simply create it.

If all of the above requirements are met, then the MWE (in this case \@test@count{❬argument❭} is used to obtain an identical task for the package command \mycommand):

\documentclass{article}
%
\makeatletter
\def\@test@count#1{%
 %mysterious (La)TeX sorcery should happen here
}
\def\mycommand[#1]#2{%
 \@test@count{#1}%
 This is the value of the counter~"#1":~\expandafter\the\csname #1\endcsname~#2\par%
}
\makeatother
%
\begin{document}
%
\mycommand[myfoo]{lorem}
\mycommand[mybar]{ipsum}
\mycommand[mybaz]{dolor}
\mycommand[myfoo]{sit}
\mycommand[mybar]{amet}
\mycommand[myfoo]{consectetur}
\mycommand[mybaz]{adipisci}
%
\end{document}

should yield:

enter image description here

The text has been inserted to show that the secondary argument can be filled without restrictions.

In the example, \mycommand[myfoo]{...} defines the counter \myfoo and sets it to 1, because there are no other counters \myfoo declared before; then \mycommand[mybar]{...} defines \mybar and so forth. When \mycommand[myfoo]{...} is called again, then a \@test@count{myfoo} will test whether \myfoo is defined, in this case it yields "true" and then the counter is advanced by 1. The same reasoning follows for any successive declaration of mybar and mybaz.

The rule for \@test@count{myfoo} will be similar to an allocation manager, because when a new counter is defined by \mycommand[myfoo]{...} it "saves" its previous value \myfoo until another \myfoo is declared: if this condition is met, then \myfoo won't be overwritten, but instead incremented.

So far I managed little to none progress to define \@test@count#1{...}, as this task requires this kind of knowledge that it's difficult for me to understand at the moment.

6

The existence of a (LaTeX) counter can be tested with \@ifundefined{c@<argument>}:

\newcommand\andrea@test@count[1]{%
  \@ifundefined{c@#1}
    {% the counter doesn't exist
     \newcounter{#1}\setcounter{#1}{1}%
    }
    {% the counter exists
     \stepcounter{#1}%
    }%
}

Full example

\documentclass{article}
%
\makeatletter
\newcommand\andrea@test@count[1]{%
  \@ifundefined{c@#1}
    {% the counter doesn't exist
     \newcounter{#1}\setcounter{#1}{1}%
    }
    {% the counter exists
     \stepcounter{#1}%
    }%
}

\newcommand\mycommand[2]{%
 \andrea@test@count{#1}%
 This is the value of the counter~"#1":~\the\value{#1}~#2\par%
}
\makeatother
%
\begin{document}
%
\mycommand{myfoo}{lorem}
\mycommand{mybar}{ipsum}
\mycommand{mybaz}{dolor}
\mycommand{myfoo}{sit}
\mycommand{mybar}{amet}
\mycommand{myfoo}{consectetur}
\mycommand{mybaz}{adipisci}
%
\end{document}

enter image description here

  • Aah! Now I understand the "newcounter"/"stepcounter" criteria, and here I was searching for some complex solution with plain TeX... I haven't realized that those commands were in fact made to simplify and enhance therir usage. Many many thanks! ;) – alandella Sep 13 '14 at 21:28

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.