0

In a memoir document class book-length document with some 2MB body content and 140K of premable, each distributed over numerous separate files, I use cleveref along with hyperref and the \tcolorboxenvironment to create a colored version of each theorem-like environment (e.g., theorem, proposition, lemma) defined by thmtools.

All the \cref links work fine except two: after full processing, the links are missing in the document. In more detail:

  • after the initial pdflatex run, one of those two label entries never appears in the .aux file, although the second label one does appear;
  • after a run of biber (or bibtex) and the 2nd run of pdflatex, the second label has now disappeared!

If I do not color the theorems, avoiding \tcolorboxenvironment, then all links are OK! So the problem does seem to have something to do with tcolorbox.

Moreover, if I do color the theorems but compile using xelatex — my preamble is configured so as to allow that, but with different fonts ‐ then the labels and links disappear from different theorems than when I use pdflatex.

This seems very strange. Unfortunately, I have been unable to reproduce the problem if I reduce the body content just to the two sections containing the theorem-like environments whose labels are used in those links.

For the actual, book-length document, after the initial pdflatex run, the .aux file includes the following two groups of consecutive lines:

  • in the first group, it is the entry for the label thm-one-pt-cptn that disappears after the 2nd pdflatex run;
  • in the second group, an entry for the label lem:path-prod ought to appear just before the lines containing {definition} but does not.

Here is the extract from the .aux:

\@writefile{loe}{\defcounter {refsection}{0}\relax }\@writefile{loe}{\contentsline {theorem}{\ifthmt@listswap Theorem~4.66\else \numberline {4.66}Theorem\fi \thmtformatoptarg {Alexandroff one-point compactification}}{482}{theorem.4.66}\protected@file@percent }
\newlabel{thm-one-pt-cptn}{{\M@TitleReference {4.66}{One-point compactification}}{482}{Alexandroff one-point compactification}{theorem.4.66}{}}
\newlabel{thm-one-pt-cptn@cref}{{[theorem][66][4]4.66}{[1][482][]482}}
\@writefile{lla}{\defcounter {refsection}{0}\relax }\@writefile{lla}{\contentsline {chapter}{\numberline {\crtrefnumber{thm-one-pt-cptn}}thm-one-pt-cptn}{482}{theorem.4.66}\protected@file@percent }        
:
:
:        
\@writefile{loe}{\defcounter {refsection}{0}\relax }\@writefile{loe}{\contentsline {definition}{\ifthmt@listswap Definition~5.51\else \numberline {5.51}Definition\fi }{526}{definition.5.51}\protected@file@percent }
\newlabel{def:path-prod}{{\M@TitleReference {5.51}{Paths}}{526}{}{definition.5.51}{}}
\newlabel{def:path-prod@cref}{{[definition][51][]5.51}{[1][526][]526}}
\@writefile{lla}{\defcounter {refsection}{0}\relax }\@writefile{lla}{\contentsline {chapter}{\numberline {\crtrefnumber{def:path-prod}}def:path-prod}{526}

A likely clue (added 2020-10-18):

For both instances of the particular theorem-like environment (modified by\tcolorboxenvironment) whose labels and links disappear, the theorem is printed at the top of the page body (below the header, of course). In the log I see this:

[485.493]

Package tcolorbox Warning: Discard zero height first box part due to break prob
lems (possible loss of zero height content) on input line 562.

[486.494]

LaTeX Warning: Reference `thm-one-pt-cptn' on page 1 undefined on input line 66
5.
:
:
[529.537]

Package tcolorbox Warning: Discard zero height first box part due to break prob
lems (possible loss of zero height content) on input line 114.

Underfull \vbox (badness 10000) has occurred while \output is active []

 [530.538]

LaTeX Warning: Reference `lem:path-prod' on page 1 undefined on input line 147.

That tcolorbox Warning does not appear anywhere else in the log, and correspondingly no other links are affected!

Temporary work-around: If for each of the two theorems affected, I move the \label command to follow the body of the theorem rather than, as would be usual keep it immediately after the \begin{theorem}, then the problem goes away. Of course this is not a solution; its a a very fragile temporary fix, because as the document content changes, other theorems could move to the top of a page and cause the same issue.

Likely explanation (not a solution!):

It seems that tcolorbox is throwing away the labels of such theorems only when they are printed at the top of the page.

Question: What fix will be robust so that tcolorbox does not throw away the label of a theorem when the theorem is printed at the top of a page?

Sample source of method used:

I'm happy to share the source of my book-length project with anybody who might help me track down this strange problem.

Meanwhile, the source below gives the flavor of what I'm doing — even though this small example does compile without error.

\documentclass{memoir}

% UTILITIES
\usepackage{ifthen}
\usepackage{xpatch}

% FONTS
\usepackage[T2A,T1]{fontenc}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{amsthm}

\usepackage[french,ngerman,polish,russian,english]{babel}

\usepackage[theoremfont]{newtxtext}
\usepackage[vvarbb]{newtxmath}
  %% Allow : in labels even with babel-french
  % Piet van Oostrum
  % https://tex.stackexchange.com/a/511212/13492
  \edef\myoldcatcode{\the\catcode`\:}
  \let\myoriglabel\label
  \def\label{\catcode`\:=11 \mynewlabel}
  \def\mynewlabel#1{\myoriglabel{#1}\catcode`\:=\myoldcatcode}

\usepackage{graphicx}
\usepackage[most]{tcolorbox}
\usepackage{tikz-cd}

\usepackage{thmtools}

% SWITCHES
\newboolean{colortitles}        % color text in section, etc., titles
\newboolean{washthms}       % apply background to theorem-like environs
\setboolean{colortitles}{true}
\setboolean{washthms}{true}

% COLORS
\definecolor{splitcompblue}{RGB}{33,103,165}
\colorlet{mythmback}{splitcompblue!5!white}
\colorlet{mytitlecolor}{splitcompblue!85!black}
\newcommand{\thmlikefont}{\sffamily\bfseries}
\ifthenelse{\boolean{colortitles}}%
  {\renewcommand{\thmlikefont}{\color{mytitlecolor}\sffamily\bfseries}}%
  {}

\usepackage[colorlinks, linkcolor=blue,linktocpage=true,linktoc=all]{hyperref}
\AtBeginDocument{\addtocontents{toc}{\protect\hypersetup{hidelinks}}}

% CROSS-REFERENCING
\usepackage[nameinlink,noabbrev,capitalize]{cleveref}
\usepackage{crossreftools}
% Fix to crossreftools
% https://tex.stackexchange.com/a/512175/13492
\makeatletter
\renewcommand{\@@crtextr@ct@ref}[2]{%
  \expandafter\@@@crtextr@ct@ref\expandafter{\detokenize{#2}}{#1}%
}
\newcommand{\@@@crtextr@ct@ref}[2]{%
  \expandafter\ifx\csname r@#1\endcsname\relax
  \crt@refundefined%
  \else
  \expandafter\expandafter\csname crt@ref@splitter@#2\endcsname\csname r@#1\endcsname%
  \fi
}
\makeatother

% TOCS
\newif\ifSHORT
\newif\ifLONG
%
\newcommand{\longtocname}{Detailed Contents}
\newcommand{\shorttocname}{Short Contents}
%
% credit for Ulrike Fischer for this idea, we need to have the
% conditionals defined **inside** the toc
\DeclareRobustCommand\activateif{%
  \let\showShort\ifSHORT
  \let\showLong\ifLONG
  \let\stopShort\fi
  \let\stopLong\fi
}
% next use patching to add a wrapper around the \addcontentsline
% that \tableofcontents generates. Since this is inside a group we
% don't having one patch messing up the other
\newcommand\shortTOC[1][2]{
  \begingroup
  \setcounter{tocdepth}{#1}
  \def\contentsname{\shorttocname}%
  \ifthenelse{\boolean{colortitles}}%
    {\renewcommand{\cftchapterfont}{\color{mytitlecolor}\bfseries\sffamily}}%
    {\renewcommand{\cftchapterfont}{\bfseries\sffamily}}%
  \xpatchcmd{\mem@tableofcontents}%
  {\addcontentsline{toc}{chapter}{\contentsname}}{%
    \addtocontents{toc}{\protect\showShort}%
    \addcontentsline{toc}{chapter}{\contentsname}
    \addtocontents{toc}{\protect\stopShort}%
  }{\typeout{ok}}{\typeout{failed}}
  \LONGtrue
  \tableofcontents
  \endgroup
}
\newcommand\longTOC[1][3]{
  \begingroup
  \setcounter{tocdepth}{#1}
  \def\contentsname{\longtocname}%
  \ifthenelse{\boolean{colortitles}}%
      {\renewcommand{\cftchapterfont}{\color{mytitlecolor}\bfseries\sffamily}%
        \renewcommand{\cftsectionfont}{\color{mytitlecolor}\bfseries\sffamily}%
      }%
      {\renewcommand{\cftchapterfont}{\bfseries\sffamily}%
        \renewcommand{\cftsectionfont}{\bfseries\sffamily}%
      }
  \xpatchcmd{\mem@tableofcontents}%
  {%
  \addcontentsline{toc}{chapter}{\contentsname}}{%
    \addtocontents{toc}{\protect\showLong}%
    \addcontentsline{toc}{chapter}{\contentsname}
    \addtocontents{toc}{\protect\stopLong}%
  }%
  {\typeout{ok}}{\typeout{failed}}
  \SHORTtrue
  \tableofcontents
  \endgroup
}
% automatically add the activation to the toc
\AtBeginDocument{
  \addtocontents{toc}{\activateif}
}

% THEOREMS
\crefname{theorem}{Theorem}{Theorems}
\Crefname{theorem}{Theorem}{Theorems}

\swapnumbers

\makeatletter
%
\declaretheoremstyle[
  headfont=\thmlikefont,
  headpunct={\thmlikefont.},
  postheadspace=0.5em,
  notefont=\thmlikefont,
  headformat=\NAME\NUMBER\let\thmt@space\@empty\NOTE,
  bodyfont=\mdseries\slshape,
  spaceabove=12pt,spacebelow=12pt,
  hidealllines=true,
  backgroundcolor={mythmback},
  innerleftmargin=8pt,innerrightmargin=8pt,
  postheadhook={%
    \ifx\@empty\thmt@shortoptarg
      \renewcommand\addcontentsline[3]{}
    \fi}
]{thmstyle}
%
\makeatother

\theoremstyle{thmstyle}
\declaretheorem[name=Theorem,numberwithin=chapter]{theorem}

\newcommand{\dowashthms}{%
%
\tcolorboxenvironment{theorem}{
  breakable,
  colback=mythmback,
  frame hidden,colframe=mythmback,
  sharp corners,
  left=2pt,right=2pt,top=2pt,bottom=2pt,
  before skip=12pt,after skip=12pt}
}

% For index
\providecommand\gobbleone[1]{}
\newcommand{\idxmark}[1]{{\let\gobbleone\relax\markboth{\sffamily\bfseries#1}{\sffamily\bfseries#1}}#1}
\ifthenelse{\boolean{washthms}}{\dowashthms}{}

\makeindex

\begin{document}

\frontmatter

\longTOC[2]
\cleardoublepage
\shortTOC[1]

\mainmatter
\chapter{Theory}

\section{Triangles}

\begin{theorem}[Pythagorean Theorem]
\label{thm:pythagoras}
\index{Pythagorean Theorem}
\index{right triangle}

The square on the hypotenuse of a right triangle equals the sums of the squares upon the other two sides.

\end{theorem}

\section{Numbers}

\begin{theorem}
\label{thm:main}
\index{main theorem}
\index{arithmetic}

$1+1=2$.

\end{theorem}

\noindent From \cref{thm:main} it follows that $2+2=4$. What does \cref{thm:pythagoras} have to do with that?
\index{arithmetic}

\backmatter
\printindex

\end{document}

Added 2020-10-17: All the packages actual document uses

Perhaps there's an issue of package load order with my actual document (although if there is, I still don't understand why the missing links occur only with two particular instances of theorem-like environments but not with others of exactly the same kind!). So gathered here are all the packages I use in the actual document, which distributes them over a number of separate .sty files that are input in the preamble.

% FROM main document:
\usepackage{iftex}
\usepackage{ifthen}
\usepackage[l2tabu,orthodox]{nag}

%%%%% FROM mypackages.sty:

\RequirePackage{xstring}    % used for \IfStrEqCase
\RequirePackage{suffix} % used for * cmds, e.g., \func*, \restrict*
\RequirePackage{calc}
\RequirePackage{etoolbox}
\RequirePackage{xpatch} % used to mod Proof style (in mathdefs.sty}
\RequirePackage{adjustbox}  % for \scalebox used to define \reverse
\RequirePackage{scalerel}   % for scalerel

%% STYLING
\RequirePackage{moresize}
\RequirePackage[strict=true]{csquotes}
\RequirePackage{multicol}
\RequirePackage{textcase} % used for theorem name key values
\RequirePackage{mfirstuc} % used for mod to ll@theorem for \listof theorems
\RequirePackage[biblatex=true]{embrac} % for upright brackets

%% ENVIRONMENTS
\RequirePackage{enumitem}

% TABLES
\RequirePackage{longtable}
\RequirePackage{makecell}

% TESTING
\usepackage[math]{blindtext}

%%%%% FROM myfonts.sty:

% FONTS & LANGUAGES
\usepackage[T2A,T1]{fontenc}
\usepackage{amsmath}    % avoid \dddot clash
\usepackage{mathtools}  % avoid unicode-math clash
\usepackage{amsthm} % avoid openbox clash

\ifTUTeX
  \usepackage{fontspec}
  \usepackage{polyglossia}
  \usepackage{unicode-math}
  \setdefaultlanguage[variant=american]{english}
  \setotherlanguages{french,german,polish,russian}
  \setmainfont{TeX Gyre Termes}[Scale=1.0]
  \defaultfontfeatures{Scale=MatchLowercase, Ligatures=TeX}
  \setmathfont{TeX Gyre Termes Math}
  \newfontfamily{\cyrillicfont}{PT Serif}
  \newcommand{\textsi}[1]{\textsc{#1}}
  \newfontfamily{\xcheckmarkfont}{LibertinusSerif-Regular.otf}
\else
  \usepackage[russian,french,ngerman,polish,english]{babel}
  \babeltags{russian=russian,french=french,german=ngerman,polish=polish}
  \usepackage{substitutefont}   % to allow non-default Cyrillic
  \substitutefont{T2A}{\rmdefault}{Tempora-TLF} % for Cyrillic
  \usepackage[theoremfont]{newtxtext}
  \usepackage{textcomp}
  \usepackage[varqu,varl]{inconsolata} % typewriter  
  \usepackage[vvarbb]{newtxmath}
% ... end font choice 
  \DeclareMathAlphabet{\mathbfsf}{\encodingdefault}{\sfdefault}{bx}{n}
  %% Allow : in labels even with babel-french
  % Piet van Oostrum
  % https://tex.stackexchange.com/a/511212/13492
  \edef\myoldcatcode{\the\catcode`\:}
  \let\myoriglabel\label
  \def\label{\catcode`\:=11 \mynewlabel}
  \def\mynewlabel#1{\myoriglabel{#1}\catcode`\:=\myoldcatcode}
  %
  \usepackage{pifont}% http://ctan.org/pkg/pifont
  \newcommand{\cmark}{\ding{51}}%
  \newcommand{\xmark}{\ding{55}}%
  \usepackage{cmap}             % for searchable, copyable unicode mapping
  \pdfmapfile{=pdftex.map}
\fi

\RequirePackage{microtype}

%%%%% FROM mymath.sty:

\RequirePackage{xfrac}
\RequirePackage{nicefrac}   % def \sfrac
% mismath defines \N, \Z, \Q, \R, \CC with mathbf
\RequirePackage{mismath}    
\RequirePackage[%
  frac,rfrac,multskip,greekcaps,greeklower,
  root,                 % root dangerous conflicts!
]{mathfixs} 
\RequirePackage{derivative}
% tools to form certain \not's:
\ifTUTeX
  \newcommand{\overlaynot}[2]{%
    \sbox\z@{$\m@th#1\notaccent{}$}%
    \sbox\tw@{$\m@th#1#2$}%
    \dimen@=\dimexpr(\ht\tw@-\ht\z@)/2\relax
    \vphantom{\raisebox{\dimen@}{\copy\z@}}%
    \ooalign{\hidewidth\raisebox{\dimen@}{\box\z@}\hidewidth\cr\box\tw@}
  }
\else
 \usepackage{centernot}
\fi
\RequirePackage{mywidebar}

%%%%% FROM mygraphics.sty:

\RequirePackage{graphicx}
\graphicspath{{graphics/}} % set graphics path
% tikz and tcolorbox load xcolor
%\RequirePackage[names,dvipsnames,named]{xcolor} 
\RequirePackage[most]{tcolorbox}
\RequirePackage{pict2e} % for \bigplus, \bigtimes defined in mymath.sty:
\RequirePackage{tikz-cd} % modify arrows in mygraphics.sty and/or lucidaarrows.sty

%%%%% FROM links.sty:

%% BIBLIOGRAPHY
\RequirePackage[
  %backend=bibtex,
  backend=biber,
  bibstyle=mybooknumeric,
  citestyle=numeric,
  dashed=true,
  defernumbers=true,
  urldate=iso,date=iso,seconds=true]%
{biblatex} 

%% NOTATION INDEX
\RequirePackage[refpage,norefeq,intoc,english,cfg]{nomencl}

%%  CROSS-REFERENCING
\RequirePackage{xurl}   % new: break URL anywhere

\RequirePackage[type={CC},modifier={by-nc-nd},version={4.0},lang={english}]{doclicense}%

\RequirePackage{hyperxmp} % to add metadata info into pdf
\usepackage[pdfa]{hyperref}

\usepackage[user,hyperref]{zref}
\RequirePackage{aliascnt}
\RequirePackage[nameinlink,noabbrev,capitalize]{cleveref}
\RequirePackage{crossreftools}

%%%%% FROM mythms.sty:
\RequirePackage{empheq}

%% THEOREM-LIKE ENVIRONMENTS
\RequirePackage{thmtools}

%%%% FROM mylists.sty:

%% ANNOTATIONS
\ifthenelse{\boolean{usefixme}}{%
  \RequirePackage[draft]{fixme}%
  \fxsetup{layout=margin,author=Fix}%
  \fxusetheme{color}%
}{}
4
  • Look at the newest issues with tcolorbox tag. There were some troubles with colors and color stacks (I think it was with xelatex). Mr. Sturm, package autor, even asked those. Also, try update tcolorbox package to newest version, because mentioned problems were resolved (just recently). It might help. – Tomáš Kruliš Oct 16 '20 at 7:39
  • @TomášKruliš: I'm using tcolorbox version 4.42 dated 2020/10/09. That's the latest version obtained from tlmgr (via TeXLive Utility) and the latest shown on ctan. – murray Oct 16 '20 at 15:39
  • The first thing I'd try to remove is nag. – egreg Oct 17 '20 at 22:26
  • @egreg: Removing the nag package makes no difference: exactly the same missing \cref references. The thing that continues to puzzle me is why it's only one particular instance of each of two kinds of \tcolorboxenvironments (based, in turn, on a theorem-like environment) that disappears. – murray Oct 18 '20 at 14:48
3
+50

The problem is typically caused by an overfull first box for breakable tcolorboxes. It is described by https://github.com/T-F-S/tcolorbox/issues/34. Unfortunately, I cannot do very much from side of the package to remove this problem, but there are some things you can do.

The following MWE provokes the 'lost label' situation:

\documentclass{article}

\usepackage{tcolorbox}
\tcbuselibrary{breakable}

\begin{document}

\begin{tcolorbox}[breakable]
\label{lab1}
\rule{2cm}{19cm}
\end{tcolorbox}
Problem: lab1 \pageref{lab1} foo

\clearpage

\begin{tcolorbox}[breakable,label=lab2]
\rule{2cm}{19cm}
\end{tcolorbox}
No problem: lab2 \pageref{lab2} foo

\clearpage

\begin{tcolorbox}[breakable]
\mbox{}\label{lab3}
\rule{2cm}{19cm}
\end{tcolorbox}
No problem: lab3 \pageref{lab3} foo

\clearpage

\begin{tcolorbox}[breakable=false]
\label{lab4}
\rule{2cm}{19cm}
\end{tcolorbox}
No problem: lab4 \pageref{lab4} foo

\end{document}

For box 1, the label lab1 is lost. A warning is found in the log file:

Package tcolorbox Warning: Discard zero height first box part due to break prob
lems (possible loss of zero height content) on input line 14.

What you can do is one of the following things:

  • Don't start a breakable box with a \label. Box 2 of the MWE uses label=lab2 which works differently. To take advantage of this, the numbering has to be done by tcolorbox instead of some embedded theorem environment. This would be the cleanest approach, but needs a redesign of your environments.

  • Put \mbox{} or \leavevmode before the \label{lab3} as done with box 3 in the MWE.

  • Insert \clearpage or \pagebreak in front of a problematic box (does not work for my MWE, but possible for your critical boxes). Also, setting breakable=false avoids the problem, if your specific box is smaller than a page.

Note that the warning Discard zero height first box part really warns you about right this problem.

2
  • Is there anything I should do, other than the above-mentioned work-arounds, if instead of using tcolorbox directly, I am using \begin{theorem} after having used thmtools to define the theorem environment and then \tcolorboxenvironment{theorem} to put it into a tcolorbox? – murray Oct 19 '20 at 15:15
  • @murray You could replace the theorem environment from thmtools by a tcolorbox theorem environment. Then, label could be used as a key. But, you would loose support of thmtools (I do not know this package in detail). Since you already have an elaborate setup, the workarounds are possibly simpler to handle than a redesign with danger of loosing features you like. – Thomas F. Sturm Oct 20 '20 at 15:11

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.