Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have two macros on my document. \showcounter increases a counter, then displays it. \resetcounter sets the counter back to "0".

\documentclass{article}
\newcounter{counterone}
\setcounter{counterone}{0}
\newcommand{\showcounter}{
    \stepcounter{counterone}
    \arabic{counterone}
}
\newcommand{\resetcounter}{
\setcounter{counterone}{0}
}
\begin{document}
    \showcounter \showcounter \showcounter %A
    \resetcounter
    \showcounter \showcounter %B
    \resetcounter
    \showcounter %C
    \resetcounter
\end{document}

This creates a counter which increases until \resetcounter is used. However, in cases where \showcounter is only used one time before \resetcounter is used, I want no value to be shown.

  • How can I hide the counter in such cases?

Update, to clarify, the output should appear like this:

(A) 1, 2, 3

(B) 1, 2

(C)

In the last case, no "1" appeared, because the counter was not used again until the next resetcounter.

share|improve this question
3  
What you are asking for is rather tricky, and I don't think it is possible to do in a single pass, because you want the behaviour of \showcounter to depend on future info: you'll need to use the aux file to record that. However, it looks like you have a higher-level goal in mind, and that might be easier to do; what is it then? –  Bruno Le Floch Dec 17 '11 at 2:19
    
The output appearance will be similar to the result of inparaenum, e.g. "This is a list: (1) fruit, (2) vegetables, (3) meat.", but where no number appears if only one item is listed. The inparaenum package will not work in my case, as the numbering flows from text, into macros, and back to text, so placing it in a list environment with \begin and \end would lead to too many problems. –  Village Dec 17 '11 at 3:05
add comment

2 Answers

Now (from the first version of your question) I assume that the following solution might exceed your TeX's capacity (maybe try lualatex then?), but I guess I can't optimize it more. An entry in the aux file is created only when actually resetting a counter with value 1; this entry defines an empty macro which is a signal to \show... not to display its argument. (This probably could be memory-optimized so that instead of creating all these macros, we create one huge macro with a list of numbers. This would most probably save memory, but increase the compilation time dramatically. Dear wizards: please confirm whether I am right here;).) An optional argument to \show... gives a macro (like \alph or \arabic) which actually displays the given counter; the user has to take care of any spaces.

Of course, you need two passes. There's no indication of this fact (like "Run LaTeX again"), however, in the log file/terminal.

Now I'd be quite happy to turn this solution into package; one use case I'd imagine would be not to number a theorem in a paper when there's only one. So any suggestions as to the user interface (including a better name for the now-idiotically-called macro \defineoneshotcounter) etc. are welcome.

Note: see Bruno Le Floch's comment below for a nice solution where \counteronestyle is the default instead of arabic (not put here in order not to clobber the code too much).

\documentclass{article}

\makeatletter

\newcommand{\defineoneshotcounter}[1]{%
  \newcounter{#1}
  \newcounter{#1@helper}
  \expandafter\newcommand\csname show#1\endcsname[1][\arabic]{%
    \stepcounter{#1}%
    \stepcounter{#1@helper}%
    \@ifundefined{#1@reset@\the\csname c@#1@helper\endcsname}{##1{#1}}{}%
  }
  \@namedef{reset#1}{%
    \ifnum\csname c@#1\endcsname=1\if@filesw
      \immediate\write\@auxout{%
        \string\global\string\@namedef{#1@reset@\the\csname c@#1@helper\endcsname}{}%
      }%
    \fi\fi
    \setcounter{#1}{0}%
  }
}

\makeatother

\defineoneshotcounter{counterone}

\newcommand{\counteronestyle}[1]{\{\arabic{#1}\}}

\begin{document}
    \showcounterone \showcounterone \showcounterone
    \resetcounterone

    \showcounterone[\alph]\showcounterone[\alph]
    \resetcounterone

    \showcounterone
    \resetcounterone

    \showcounterone[\counteronestyle]\showcounterone[\counteronestyle]%
    \showcounterone[\counteronestyle]\showcounterone[\counteronestyle]
    \resetcounterone

    \showcounterone
    \resetcounterone

    \showcounterone \showcounterone
    \resetcounterone
\end{document}
share|improve this answer
1  
When building a command with an optional argument, LaTeX creates several TeX macros, whose name is built from the command's name. So one \let is not enough to copy \@tempa and the auxiliaries. Instead you should simply do \expandafter\newcommand\csname show#1\endcsname etc. Also, it would seem more logical to use \counteronestyle by default. Perhaps with \expandafter\newcommand\csname show#1\expandafter\endcsname\expandafter[\expandafter1\expandafter]\expandafter[‌​\csname #1style\endcsname]{...}? –  Bruno Le Floch Dec 17 '11 at 3:42
    
Good point, how stupid of me! I corrected this. As for the second suggestion: nice trick, I'll put it in the package when I write it, here (for the sake of simplicity) I'll leave it that way. –  mbork Dec 17 '11 at 3:50
2  
To get the rerun warning, you could use the ctan.org/pkg/rerunfilecheck package, which notices changes in the aux file and gives a rerun warning. –  Stephen Dec 17 '11 at 19:09
    
Thanks, I'll check it out! –  mbork Dec 18 '11 at 0:49
    
There is a problem with your solution : see tex.stackexchange.com/questions/44529/… . –  projetmbc Feb 14 '12 at 17:49
add comment
\begin{filecontents*}{disccounters.sty}
\RequirePackage{keyval2e}
\long\def\gobble@to@relax#1\cpt@relax{}
\kve@definekeys[DC]{disccount}[disc@]{%
  format/\@firstofone,
  numbertype/\arabic/
    \ifescapedTF{#1}{%
      \xifinsetTF{,\detokenize{#1},}{%
        ,\detokenize{\arabic,\alph,\Alph},%
      }{}{%
        \@latex@error{Invalid number type '\detokenize{#1}'}\@ehc
      }%
    }{%
      \@latex@error{Number type '\detokenize{#1}' must be escaped}\@ehc
    },
}
\newcounter{disccounter@aux}
\BeforeStartOfDocument{%
  \ifdefTF\disccounter@hook{}{%
    \def\disccounter@hook{}%
  }%
}
\newcommand*\discc@unter@aux{\the\numexpr\thedisccounter@aux-20000\relax}
\robust@def*\DefineDiscCounters{\cpt@testopt\disc@definecounters{}}
\robust@def*\disc@definecounters[#1]#2{%
  \cptexpandargonce{\kve@setafterdefaults[DC]{disccount}}{#1}%
  \setcounter{disccounter@aux}{0}%
  \docommalist{#2}{%
    \newcounter{##1}%
    \expandafter\newcommand\csname show##1\endcsname[1][]{%
      \stepcounter{##1}%
      \stepcounter{disccounter@aux}%
      \cptexpandargonce{\kve@setafterdefaults[DC]{disccount}}{####1}%
      \xifinsetTF{,##1@reset@\discc@unter@aux,}%
        {,\disccounter@hook,}{}{\disc@format{\disc@numbertype{##1}}}%
    }%
    \csn@def{reset##1}{%
      \ifnum\csname c@##1\endcsname=\@ne
        \xifinsetTF{,##1@reset@\discc@unter@aux,}{,\disccounter@hook,}{}{%
          \xdef\disccounter@hook{%
            \ifcsemptyTF\disccounter@hook{}{\disccounter@hook,}%
            ##1@reset@\discc@unter@aux
          }%
        }%
      \fi
      \setcounter{##1}{0}%
    }%
  }%
}
\AtEndDocument{%
  \if@filesw
    \immediate\write\@auxout{%
      \gdef\string\disccounter@hook{\disccounter@hook}%
    }%
  \else
    \@latex@warning@no@line{File '\jobname.aux' not open}%
  \fi
}
\newcommand*\discbraced[1]{{\tt\string{#1\string}}}
\endinput
\end{filecontents*}

\documentclass{article}
\usepackage{disccounters}
\usepackage{color}
\DefineDiscCounters[numbertype=\arabic]{counterone,countertwo,counterthree}

\begin{document}
\begin{enumerate}
% If you hate the optional argument, you can use the plain \show... 
% (without argument), or put the optional arguments in a command (see later).
\item \showcounterone \showcounterone \showcounterone
  \resetcounterone
\item \showcounterone[numbertype=\alph]\showcounterone[numbertype=\alph]%
  \resetcounterone
\item \showcounterone
  \resetcounterone
\item \showcounterone[numbertype=\arabic]\showcounterone[numbertype=\arabic]%
  \showcounterone[numbertype=\arabic]\showcounterone[numbertype=\arabic]%
  \resetcounterone
\item \showcounterone
  \resetcounterone
\item \showcounterone[numbertype=\Alph]\showcounterone[numbertype=\Alph]
  \resetcounterone
\end{enumerate}

\begingroup
\color{red}
\begin{enumerate}
\item \showcountertwo \showcountertwo \showcountertwo
  \resetcountertwo
\item \showcountertwo[numbertype=\alph]\showcountertwo[numbertype=\alph]%
  \resetcountertwo
\item \showcountertwo
  \resetcountertwo
\item \showcountertwo[numbertype=\arabic]\showcountertwo[numbertype=\arabic]%
  \showcountertwo[numbertype=\arabic]\showcountertwo[numbertype=\arabic]%
  \resetcountertwo
\item \showcountertwo
  \resetcountertwo
\item \showcountertwo \showcountertwo
  \resetcountertwo
\end{enumerate}
\endgroup

\begingroup
\color{blue}
\def\tempa{numbertype=\alph,format=\discbraced}
\def\tempb{numbertype=\arabic,format=\discbraced}
\begin{enumerate}
\item \showcounterthree \showcounterthree \showcounterthree
  \resetcounterthree
\item \showcounterthree[\tempa]%
  \showcounterthree[numbertype=\Alph,format=\discbraced]%
  \resetcounterthree
\item \showcounterthree
  \resetcounterthree
\item \showcounterthree[\tempb]\showcounterthree[\tempb]%
  \showcounterthree[\tempb]\showcounterthree[\tempb]%
  \resetcounterthree
\item \showcounterthree
  \resetcounterthree
\item \showcounterthree \showcounterthree
  \resetcounterthree
\end{enumerate}
\endgroup

\end{document}

enter image description here

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.