11

Inspired by this great answer, I'm trying to typeset my definitions using tcolorbox. My document contains hundreds of definitions which follow the pattern:

\begin{definition}
% ...
\label{something:meaningful}
\end{definition}

My problem is that I haven't found a way to define a definition environment based on tcolorbox where the labels work as expect. To demonstrate the problem, I have created a MWE:

\documentclass[12pt]{book}

\usepackage[paperheight=100in]{geometry} % just to allow taking a screen shot...
\usepackage[most]{tcolorbox}

% this is my current "definition" environment
\newtcolorbox[auto counter,number within=chapter]{definition}{
  enhanced,
  breakable,
  fonttitle=\sc,
  title={Definition \thetcbcounter}
}
\let\clearpage\relax % also to allow a screenshot

\begin{document}

\chapter{First Chapter}
\section{Section 1}
\begin{definition}
A first definition. Labeled \texttt{def:A}.
\label{def:A}
\end{definition}

\section{Section 2}
\begin{definition}
Another definition. Labeled \texttt{def:B}.
\label{def:B}
\end{definition}

\subsection{With a Subsection}
\begin{definition}
Another definition -- this time nested. Labeled \texttt{def:C}.
\label{def:C}
\end{definition}

\chapter{Second Chapter}
\begin{definition}
Definition in the second chapter. Labeled \texttt{def:D}.
\label{def:D}
\end{definition}

Judging from the definition headers, it looks like the per-chapter-counter seems to work.
But lets see what happens if we reference the definitions.
\begin{itemize}
  \item \texttt{\textbackslash ref\{def:A\}} refers to Definition \ref{def:A}.
  \item \texttt{\textbackslash ref\{def:B\}} refers to Definition \ref{def:B}.
  \item \texttt{\textbackslash ref\{def:C\}} refers to Definition \ref{def:C}.
  \item \texttt{\textbackslash ref\{def:D\}} refers to Definition \ref{def:D}.
\end{itemize}


\end{document}

So I'm using an auto-counter on a per chapter basis. This counter itself also seem to work, since the header of my definitions have a correct per-chapter numbering. The problem is that referring to the labels does not give the same number. This is the output of the above MWE:

output

In fact it looks like the labels simply refer to the surrounding chapter/section. Is there a way to make the labels consistent with the definition number?

I have discovered that there is an optional label argument for environments defined by newtcolorbox. However, I haven't found a way to use it in my case. I guess it only works for environments that have a mandatory argument, and I don't want to break compatibility to all my existing definitions following the above pattern.

10

Use the label key for the tcolorbox:

\documentclass[12pt]{book}
\usepackage[most]{tcolorbox}

% this is my current "definition" environment
\newtcolorbox[auto counter,number within=chapter]{definition}[1][]{
  enhanced,
  breakable,
  fonttitle=\scshape,
  title={Definition \thetcbcounter},
  #1
}

\begin{document}

\chapter{First Chapter}
\section{Section 1}
\begin{definition}[label=def:A]
A first definition. Labeled \texttt{def:A}.
\end{definition}

\section{Section 2}
\begin{definition}[label=def:B]
Another definition. Labeled \texttt{def:B}.
\end{definition}

\subsection{Whit a Subsection}
\begin{definition}[label=def:C]
Another definition -- this time nested. Labeled \texttt{def:C}.
\end{definition}

\chapter{Second Section}
\begin{definition}[label=def:D]
Definition in the second chapter. Labeled \texttt{def:D}.
\end{definition}

Judging from the definition headers, it looks like the per-chapter-counter seems to work.
But lets see what happens if we reference the definitions.
\begin{itemize}
  \item \texttt{\textbackslash ref\{def:A\}} refers to Definition \ref{def:A}.
  \item \texttt{\textbackslash ref\{def:B\}} refers to Definition \ref{def:B}.
  \item \texttt{\textbackslash ref\{def:C\}} refers to Definition \ref{def:C}.
  \item \texttt{\textbackslash ref\{def:D\}} refers to Definition \ref{def:D}.
\end{itemize}


\end{document}

enter image description here

In my example, I used

\newtcolorbox[auto counter,number within=chapter]{definition}[1][]{
  enhanced,
  breakable,
  fonttitle=\scshape,
  title={Definition \thetcbcounter},
  #1
}

so the label has to be passed as an optional argument:

\begin{definition}[label=<text>]
...
\end{definition}

but you could also say

\newtcolorbox[auto counter,number within=chapter]{definition}[1][]{
  enhanced,
  breakable,
  fonttitle=\scshape,
  title={Definition \thetcbcounter},
  label=#1
}

and then simply

\begin{definition}[<text>]
...
\end{definition}

Or you could make this a mandatory argument.

Remark

The theorems library from tcolorbox allows one to use

\newtcbtheorem[<init options>]{<name>}{<display name>}{<options>}{<prefix>}

and then

\begin{name}{}{<label>}
...
\end{name}

so one can say \ref{<prefix:<label>} to get cross-references. I didn't use this in the answer linked in the question since there no numbering (so no cross-referencing) was required.

4
  • 1
    Hm, this means that I have to edit hundreds of definitions. There is no way to automate this to keep my existing use patterns? – bluenote10 Mar 4 '15 at 18:44
  • @bluenote10 I'll have to look at the code to see how tcolorbox handles the labels internally, but this will have to wait. Perhaps, in the meantime, someone else will provide a better alternative. – Gonzalo Medina Mar 4 '15 at 18:50
  • Ok, thanks a lot. I'm glad to have any solution at all. The reason why I didn't use newcbtheorem in the first place was just that I was trying to avoid refactoring all definitions/labels. – bluenote10 Mar 4 '15 at 18:57
  • @GonzaloMedina This does not allow you to use \nameref with the correct name-the value of the title key, however. Is this correct? It did not work with my test. Maybe I am missing something. – Jonathan Komar Apr 15 '16 at 6:58
3

Here is a way to make \label work inside a tcolorbox – but this is really dirty and only works under the assumption, that the \label command immediately follows the \begin{definition} command!

It works by "catching" the \label token using xparses t argument. To use xparse we have to create the environment by hand and not by the means of the theorem library.

An advantage of this ugly hack is the fact, that the autocomplete features of some tex(t)-editors should be able to find the labels defined this way, whereas the ones created with [label=def:test] will not be found – at least "out-of-the-box".

Consider the following MWE:

\documentclass{article}
\usepackage{cleveref}
\usepackage{tcolorbox}
\tcbuselibrary{xparse,skins,breakable}

\tcbset{%
    basestyle/.style={enhanced,breakable,
        fonttitle=\scshape,
        coltitle=white},
    defstyle/.style={basestyle,colback=red!10!white},
    theostyle/.style={basestyle,colback=blue!10!white},
}
\DeclareTColorBox[auto counter,number within=section,crefname={definition}{definitions}]{definition}{ o O{} t\label g }{%
    defstyle,IfValueTF={#1}{title={Definition~\thetcbcounter\ (#1)}}{title=Definition~\thetcbcounter}, IfBooleanTF={#3}{label=#4}{},#2}

\begin{document}

\begin{definition}[My title]\label{def:test}
    Foo.
\end{definition}

This was \cref{def:test}.
Unlabeled definition:

\begin{definition}[Cool Title][colback=orange!10!white]
    Just a test.
\end{definition}

\end{document}

Output: enter image description here

1
  • Hey Jannes ^^, bin auf das gleiche Problem gestoßen: Die tcolorbox hat einfach einen echt nicht sehr kompatiblen Syntax für Theoreme, kopf-schüttel. Jo nette Lösung! :) – C-Star-W-Star Sep 7 '18 at 22:53
1

PLEASE consider using @Gonzola's answer as it is the appropriate way to proceed. A text editor that provides a good regular expressions functionality should allow you to patch your document in a single "search and replace" type of manner.

I have attempted to use the number freestyle option for \newtcolorbox as described in the package documentation, but even this does not seem to work, so I am guessing there is a bug in the tcolorbox package (how the reference is defined?)... but this is purely speculative.

Nonetheless, here is a terrible solution that will work. To apply this to your current document, you will simply have to search for every occurence of \label{def: and replace it with \addtocounter{definition}{-1}\refstepcounter{definition}\label{def:.

With this code, the labels will remain consistent whether or not you define a \labelin every definition.

The code:

\documentclass[12pt]{book}

\usepackage[paperheight=100in]{geometry} % just to allow taking a screen shot...
\usepackage[most]{tcolorbox}

%% Create a new counter that will follow tcolorbox's numbering
\newcounter{definition}[chapter]
\renewcommand*{\thedefinition}{\noexpand\thechapter.\noexpand\arabic{definition}}

% this is my current "definition" environment
\newtcolorbox[auto counter,number within=chapter]{definition}{
  enhanced,
  breakable,
  fonttitle=\sc,
  title={Definition \thetcbcounter\refstepcounter{definition}}
}
\let\clearpage\relax % also to allow a screenshot

\begin{document}

\chapter{First Chapter}
\section{Section 1}
\begin{definition}
A first definition. Labeled \texttt{def:A}.
\addtocounter{definition}{-1}\refstepcounter{definition}\label{def:A}
\end{definition}

\section{Section 2}
\begin{definition}
Another definition. Labeled \texttt{def:B}.
\addtocounter{definition}{-1}\refstepcounter{definition}\label{def:B}
\end{definition}

\subsection{Definition without label}
\begin{definition}
Another definition -- this time without label.
\end{definition}

\subsection{Whit a Subsection}
\begin{definition}
Another definition -- this time nested. Labeled \texttt{def:C}.
\addtocounter{definition}{-1}\refstepcounter{definition}\label{def:C}
\end{definition}

\chapter{Second Chapter}
\begin{definition}
Definition in the second chapter. Labeled \texttt{def:D}.
\addtocounter{definition}{-1}\refstepcounter{definition}\label{def:D}
\end{definition}

Judging from the definition headers, it looks like the per-chapter-counter seems to work.
But lets see what happens if we reference the definitions.
\begin{itemize}
  \item \texttt{\textbackslash ref\{def:A\}} refers to Definition \ref{def:A}.
  \item \texttt{\textbackslash ref\{def:B\}} refers to Definition \ref{def:B}.
  \item \texttt{\textbackslash ref\{def:C\}} refers to Definition \ref{def:C}.
  \item \texttt{\textbackslash ref\{def:D\}} refers to Definition \ref{def:D}.
\end{itemize}


\end{document}

The output:

Output of the above code

1
  • As a sidenote, both \noexpands aren't necessary in the \thedefinition redefinition: they are simply relics of tests I was conducting with the number freestyle option for \newtcolorbox. – feculededentier Mar 5 '15 at 0:52

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.