8

I'm writing a mathematical paper, and right now I'm using

\newtheorem{theorem}{Theorem}[section]

to enumerate theorems, propositions, etc. In this way, every statement shows the number of the chapter, the number of the section and then the number of the statement in that section.

This is quite standard, but I would like to do it something differently: I'd like to omit the chapter number when stating the propositions, but show it every time I'm referring to that proposition outside the chapter.

I've already seen it in some books, is there an easy way to do it?

7

Here is what you want

Theorem's label

\renewcommand{\thetheorem}{\arabic{section}.\arabic{theorem}}

LaTex uses a prefix \p@counter for cross-referencing i.e. a reference to a theorem produce \p@theorem\thetheorem

in this case \p@theorem= null inside chapter and \p@theorem=chapter number outside.

\p@theorem=\ifnum\thechapter=chapter of theorem\else\thechapter.\fi

we do this with

\renewcommand{\p@theorem}{\string\ifnum\string\thechapter=\thechapter\string\else\thechapter.\string\fi}

Note: \string for aux writing without expantion

\documentclass{book}
\newtheorem{theorem}{Theorem}[section]
\renewcommand{\thetheorem}{\arabic{section}.\arabic{theorem}}
\makeatletter
\renewcommand{\p@theorem}{\string\ifnum\string\thechapter=\thechapter\string\else\thechapter.\string\fi}
\makeatother
\begin{document}
\chapter{Foo}
bla bla bla
\section{Bar}
\begin{theorem}\label{th:first}
test
\end{theorem}
\ref{th:first}
\begin{theorem}\label{th:second}
test
\end{theorem}
\begin{theorem}\label{th:last}
test
\end{theorem}

\chapter{BAR}
bla bla bla
\section{Baz}
\begin{theorem}
test
\end{theorem}
\ref{th:first}
\end{document}
  • What's particularly nifty about your solution is that it works seamlessly with the hyperref and cleveref packages. – Mico Aug 22 '15 at 20:39
  • Is there a way to modify your solution so that it can handle lettered (A, B, C...) as well as numbered (1, 2, 3...) chapter "numbers"? – Mico Aug 26 '15 at 8:28
  • 1
    @Mico we can do \renewcommand{\p@theorem}{\string\if\string\thechapter\string\detokenize{\thechapter}\string\relax\protect\else\thechapter.\protect\fi}. I will edit my answer – touhami Aug 26 '15 at 9:17
  • @Mico this will fail if chapter number >9. I will try, but i think this will drive me to egreg's method. – touhami Aug 26 '15 at 16:57
  • Many thanks for your answer, and for looking into how your approach might be extended to handle chapter "numbers" that don't use arabic numbers but, say, alphabetic letters or Roman numerals. – Mico Aug 29 '15 at 7:05
5
+100

Extending touhami's idea, but making it work also for nonstandard chapter numbers (like for theorems in an appendix), I make \p@theorem expand to \compare@theorem{\thetheorem}, where \compare@theorem is a protected macro; thus only \thetheorem is expanded when writing to the .aux file. The macro \compare@theorem uses \pdfstrcmp (under the abstraction \pdf@strcmp provided by pdftexcmds so the code works also with XeLaTeX and LuaLaTeX): with it the comparison is between strings, not numeric.

\documentclass{book}
\usepackage{pdftexcmds}

\newtheorem{theorem}{Theorem}[section]

\renewcommand{\thetheorem}{\arabic{section}.\arabic{theorem}}

\makeatletter
\protected\def\compare@theorem#1{%
  \ifnum\pdf@strcmp{#1}{\thechapter}=\z@
  \else
    #1.%
  \fi
}
\renewcommand{\p@theorem}{\compare@theorem{\thechapter}}
\makeatother

\begin{document}
\chapter{Foo}
bla bla bla
\section{Bar}
\begin{theorem}\label{th:first}
test
\end{theorem}
\ref{th:first}
\begin{theorem}\label{th:second}
test
\end{theorem}
\begin{theorem}\label{th:last}
test
\end{theorem}

\chapter{BAR}
bla bla bla
\section{Baz}
\begin{theorem}
test
\end{theorem}
\ref{th:first}

\ref{th:app}

\appendix

\chapter{APP}

\section{Aps}

\begin{theorem}\label{th:app}
test
\end{theorem}

\ref{th:app}

\end{document}
  • Many thanks for this answer, which can handle several enumeration styles (e.g., arabic, alphabetic, and Roman numerals) and works seemlessly with cross-referencing packages such as hyperref and cleveref (and a few more as well, I guess). – Mico Aug 29 '15 at 7:07
3

The following solution weighs way more than the rather clever approach of @touhami; in exchange you gain more flexibility regarding changes to the theorem interface.

How to use it: After defining a new theorem environment using \newtheorem you can use the new command \theoremnum to specify a numbering that is indipendent from the reference mechanism. (The additional property that references within the same chapter should display the same numbering as the theorems they refer to is covered.) In your case you would declare:

\theoremnum{theorem}{\arabic{section}.\arabic{theorem}}

after \newtheorem{theorem}{Theorem}[section] to get rid of the chapter number.

output_part-1

output_part-2

output_part-3

Complete code

\documentclass{report}
\usepackage{xstring}

\makeatletter
\newcommand{\theoremnum}[2]{%
  \expandafter\let\csname the#1@\expandafter\endcsname\csname the#1\endcsname
  \expandafter\def\csname the#1\endcsname{#2}
  \expandafter\def\csname label@#1\endcsname##1{%
    \@bsphack
    \protected@write\@auxout{}%
      {\string\newlabel{##1}{{\csname the#1\endcsname}{\thepage}}}%
    \protected@write\@auxout{}%
      {\string\newlabel{##1@full}{{\csname the#1@\endcsname}{\thepage}}}%
    \@esphack%
  }
  \expandafter\g@addto@macro\csname #1\endcsname{%
    \expandafter\let\csname label\expandafter\endcsname\csname label@#1\endcsname%
  }
}
\let\orig@ref\ref
\renewcommand{\ref}[1]{%
  \NumBefore{\orig@ref{#1@full}}[\@refchapter]%
  \ifnum\thechapter=\@refchapter\relax
    \orig@ref{#1}
  \else
    \orig@ref{#1@full}
  \fi%
}
\def\NumBefore#1{%
  \kernel@ifnextchar[{\NumBefore@{#1}}{\NumBefore@{#1}[]}%
}
\def\NumBefore@#1[#2]{%
  \begingroup\edef\x{\endgroup\noexpand\find@sep#1.\relax}\x
  \StrBefore{#1}{\@sep}[#2]%
}
\def\find@sep#1#2\relax{%
  \if<\ifnum9<1#1<\else>\fi
    \expandafter\find@sep#2.\relax%
  \else
    \def\@sep{#1}%
  \fi
}
\makeatother

\newtheorem{theorem}{Theorem}[section]
\theoremnum{theorem}{\arabic{section}.\arabic{theorem}}

\begin{document}
\chapter{baz}
\section{zzzzz}

\noindent Reference to \verb|thm:test| \emph{outside} of chapter `foo': \ref{thm:test}

\chapter{foo}
\section{zzz}

\begin{theorem}
  \label{thm:test}
  Test theorem.
\end{theorem}

\noindent Reference to \verb|thm:test| \emph{inside} of chapter `foo': \ref{thm:test}

\chapter{bar}
\section{zzzz}

\noindent Reference to \verb|thm:test| \emph{outside} of chapter `foo': \ref{thm:test}
\end{document}

Note: The way this solution uses redefinitions of the cross-referencing mechanism it won't be usable with heyperref. If that is a criterion you better go with the other solution.

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.