4

(A question related to this one and leading up to this one.)

Suppose I'm using ntheorem. I would like to have a command which determines the name (not the value) of the counter associated with a certain theorem-like environment. Thus, the following:

\documentclass{article}
\usepackage{ntheorem}
\newtheorem{theorem}{Theorem}[section]
\newtheorem{prop}[theorem]{Proposition}
\begin{document}
Propositions use the counter \getenvcounter{prop} while theorems use \getenvcounter{theorem}.
\end{document}

Should produce

Propositions use the counter theorem while theorems use theorem.

I can tolerate the use of cleveref if necessary...

einpoklum
  • 12,311

2 Answers2

6
\makeatletter
\def\getenvcounter#1{%
  \expandafter\expandafter\expandafter\@getenvcounter\csname mkheader@#1\endcsname}
\def\@getenvcounter\csname#1\endcsname#2#3#4#5{#4}
\makeatother

Explanation: \show\prop gives

> \prop=macro:
->\let \thm@starredenv \@undefined \csname mkheader@prop\endcsname .

Then \show\mkheader@prop gives

> \mkheader@prop=macro:
->\csname setparms@prop\endcsname \@thm {prop}{theorem}{Proposition}.

So I expand twice \csname mkheader@#1\endcsname, which gives the token list shown last and define \@getenvcounter accordingly.

The version for the LaTeX kernel definition (kept by amsthm) would be

\makeatletter
\def\getenvcounter#1{%
  \expandafter\expandafter\expandafter\@getenvcounter\csname#1\endcsname}
\def\@getenvcounter#1#2#3{#2}
\makeatother

Common version

If you prefer a version that doesn't depend on package loading, here it is:

\makeatletter
\def\getenvcounter#1{%
  \@ifundefined{mkheader@#1}
    {\expandafter\expandafter\expandafter\@getenvcounterkernel\csname#1\endcsname}
    {\expandafter\expandafter\expandafter\@getenvcounterntheorem\csname mkheader@#1\endcsname}}
\def\@getenvcounterkernel#1#2#3{#2}
\def\@getenvcounterntheorem\csname#1\endcsname#2#3#4#5{#4}
\makeatother

Version supporting also thmtools

\makeatletter
\def\getenvcounter#1{%
  \@ifundefined{mkheader@#1}
    {\expandafter\expandafter\expandafter\@getenvcounterkernel
     \csname\ifcsname thmt@original@#1\endcsname thmt@original@\fi#1\endcsname}
    {\expandafter\expandafter\expandafter\@getenvcounterntheorem\csname mkheader@#1\endcsname}}
\def\@getenvcounterkernel#1#2#3{#2}
\def\@getenvcounterntheorem\csname#1\endcsname#2#3#4#5{#4}
\makeatother
egreg
  • 1,121,712
1

If you're willing to use cleveref, then also loading crossreftools allows you to determine the counter in question by referencing just any one theorem-like environment by its label:

\documentclass{article}
\usepackage{ntheorem}
\newtheorem{theorem}{Theorem}[section]
\newtheorem{prop}[theorem]{Proposition}
\usepackage{cleveref}
\usepackage{crossreftools}

\begin{document}

\begin{theorem}\label{mythm}
This is a theorem.
\end{theorem}

\begin{prop}\label{just-a-prop}
And this is a proposition.
\end{prop}

My theorem uses the counter '\crtcrefcounter{mythm}' whereas my proposition uses the counter '\crtcrefcounter{just-a-prop}'.

\end{document}

Use crossreftools to get counters associated with theorem-like enviornments

The crossreftools package also works with thmtools. It includes other handy tools related to cross-referencing.

murray
  • 7,944