28

I've written a package that introduces a new environment:

\newfloat{foo}{htb}{bar}[chapter]

The package however can be used for articles, books, ... Since not all of these environments have the concept of chapter, on gets a No counter 'chapter' defined. exception.

How can I check if the chapter counter is defined?

0

3 Answers 3

27

If a counter foo exists then a count \c@foo exists as well as a macro \thefoo. The \newcounter command (that most likely is used by \newfloat) actually checks if \c@foo exists and calls \@nocounterr{foo} if it doesn't.

The following also checks for \c@foo using etex's \ifcsname ...\endcsname:

\documentclass{article}

\makeatletter
\newcommand*\ifcounter[1]{%
  \ifcsname c@#1\endcsname
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\makeatother

\begin{document}

Counter \texttt{chapter} \ifcounter{chapter}{exists}{doesn't exist}.

Counter \texttt{section} \ifcounter{section}{exists}{doesn't exist}.

\end{document}

enter image description here

6
  • 3
    \newcommand\ifcounter[3]{\@ifundefined{c@#1}{#3}{#2}}
    – egreg
    Jan 24, 2014 at 15:08
  • 3
    @egreg I know :) I just like \ifcsname a tiny bit better since it doesn't leave the command as \relax if it isn't defined
    – cgnieder
    Jan 24, 2014 at 15:10
  • 1
    @egreg completely agree with clemens, see a good explanation of this issue here. Oct 11, 2015 at 17:23
  • Why are the \expandafters needed? I figured that the conditional would expand to \@firstoftwo (or \@secondoftwo), and we'd be left with \@firstoftwo{exists}{doesn't exist}. Dec 21, 2018 at 17:29
  • @Beelzebielsk see tex.stackexchange.com/questions/107753/…
    – cgnieder
    Dec 23, 2018 at 11:57
13
\documentclass{article}
\usepackage{float}
\usepackage{etoolbox}
\ifdef{\thechapter}{\newfloat{foo}{htb}{bar}[chapter]}{}
\begin{document}%
x
\end{document}
3

A TeX version of the conditional. Clemens used the e-TeX \ifcsname conditional. I just translated it into the TeX \ifx. I got inspired in this answer.

\documentclass{article}

\begin{document}

 Counter \texttt{chapter} 
 \makeatletter   
 \ifx\c@chapter\undefined
    doesn't exist
 \else
    it exists
 \fi
\makeatother

 Counter \texttt{section}   
 \makeatletter  
 \ifx\c@section\undefined
    doesn't exist
 \else
    exists
 \fi
 \makeatother

 \end{document}

The output is exactly the same as the first answer. May be somebody can tell the advantages/disadvantages compared with the others.

3
  • The \ifcsname approach doesn't rely on \undefined to really be undefined.
    – egreg
    Oct 11, 2015 at 21:03
  • Is this a shortcoming to rely on \undefined? Oct 11, 2015 at 21:06
  • 2
    Not really, but one should be trustful of package writers, but especially of users, who are fond of giving strange names to their macros. Thus \@undefined seems a better choice.
    – egreg
    Oct 11, 2015 at 21:08

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.