2

Only the first numbered environment created with tcolorbox gets an <a> tag destination in the HTML when converted with htlatex. Consider the following MWE:

\documentclass{article}

\usepackage[most]{tcolorbox}
\usepackage{cleveref}
\newtcbtheorem{theorem}{}{}{th}
\crefname{tcb@cnt@theorem}{theorem}{theorems}

\begin{document}

\begin{theorem}{}{1}
    Text
\end{theorem}

\begin{theorem}{}{2}
    Text
\end{theorem}

\end{document}

This results in the following HTML:

<div class="tcolorbox theorem" id="tcolobox-1">
  <a id="x1-1doc"></a> 
  <div class="tcolorbox-title">...</div>
  <div class="tcolorbox-content">...</div>
</div>
<div class="tcolorbox theorem" id="tcolobox-2">
  <div class="tcolorbox-title">...</div>
  <div class="tcolorbox-content">...</div> 
</div>

Here, only the first theorem got the <a id="x1-1doc"></a> tag. Cross references to the theorems, \cref{th:1} and \cref{th:2}, yield "theorem 1" and "theorem 2", but both link to the first one: <a href="#x1-1doc">. Moreover, a plain \ref{th:1} does not produce any output.

Is there a way to give every instance of theorem a unique <a> tag destination? Moreover, this should also work for other environments defined via tcolorbox. Lastly, is there a way to get \ref to work for these environments?

UPDATE

michal.h21 posted a solution that ensures that every environment has a unique link destination. This works fine if the document only uses one type of environment defined via tcolorbox. However, consider the following example:

\documentclass{article}

\usepackage[most]{tcolorbox}
\usepackage{cleveref}
\newtcbtheorem{theorem}{Theorem}{}{th}
\newtcbtheorem{lemma}{Lemma}{}{lem}
\crefname{tcb@cnt@theorem}{theorem}{theorems}
\crefname{tcb@cnt@lemma}{lemma}{lemmas}

\begin{document}

\begin{theorem}{}{1}
    Text
\end{theorem}

\begin{theorem}{}{2}
    Text
\end{theorem}

\begin{lemma}{}{}
    Text
\end{lemma}

See \cref{th:1} and \cref{th:2}.

\end{document}

This renders as enter image description here Here the last reference is incorrectly printed as "lemma 1" instead of "theorem 2". How can this be fixed?

1 Answer 1

2

TeX4ht needs special treatment for labels. It works out of the box for commands and environments that update their counters using \refstepcounter, but it seems that tcolorbox uses it's own mechanism for label handling. In this case, we need to insert destination link for the current label using \AnchorLabel command. This is the updated version of tcolorbox.4ht that uses it:

% tcolorbox.4ht (2020-12-03-13:56), generated from tex4ht-4ht.tex
% Copyright 2020 TeX Users Group
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3c of this license or (at your option) any
% later version. The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions
% of LaTeX version 2005/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
%
% The Current Maintainer of this work
% is the TeX4ht Project <http://tug.org/tex4ht>.
%
% If you modify this program, changing the
% version identification would be appreciated.
\immediate\write-1{version 2020-12-03-13:56}


% use custom counter that increments for every \tcolorbox
\newcounter{:tcbcolcount}

\def\tcb@drawcolorbox{%
  % save text and background colors for use in CSS
  \stepcounter{:tcbcolcount}%
  \get:xcolorcss{tcbcolbacktitle}\:tcbcolbacktitle%
  \get:xcolorcss{tcbcoltitle}\:tcbcoltitle%
  \get:xcolorcss{tcbcolback}\:tcbcolback%
  \get:xcolorcss{tcbcolframe}\:tcbcolframe%
  \get:xcolorcss{tcbcolupper}\:tcbcolupper%
  % make unique ID for this box
  \def\:tcbcolid{tcolobox-\arabic{:tcbcolcount}}
  % Open box
  \a:tcolorbox%
  % save label, if it is set
  \ifdefined\tcolorbox:label:key%
    \AnchorLabel%
    \label{\tcolorbox:label:key}%
    \global\let\tcolorbox:label:key\undefined
  \fi%
  % open title
  \b:tcolorbox%
  \kvtcb@before@title\kvtcb@title\kvtcb@after@title%
  % close title and open main box
  \c:tcolorbox%
  \box\tcb@upperbox%
  % deal with lower box, if it is set
  \iftcb@hasLower%
    \a:tcolorlowerbox%
    \box\tcb@lowerbox%
    \b:tcolorlowerbox%
  \fi%
  % close box
  \d:tcolorbox%
}

% overwrite other versions of box drawing macros
\let\tcb@drawcolorbox@standalone\tcb@drawcolorbox

\NewConfigure{tcolorbox}{4}
\NewConfigure{tcolorlowerbox}{2}

% we need to save label for a later use
\def\:tempa#1{%
  \xdef\tcolorbox:label:key{#1}%
  \o:tcb@set@label:{#1}%
}
\HLet\tcb@set@label\:tempa


% this is a trick to fix issues with paragraphs
% spurious end </p> tags were inserted
\def\tcb@minipage#1{\SaveEndP\vbox\bgroup\par}
\def\endtcb@savebox{\EndP\egroup\RecallEndP}

\Hinput{tcolorbox}
\endinput

The changed code is this:

  \ifdefined\tcolorbox:label:key%
    \AnchorLabel%
    \label{\tcolorbox:label:key}%
    \global\let\tcolorbox:label:key\undefined
  \fi%

It inserts the link destination just before \label.

This is the resulting HTML code:

 <div class='tcolorbox theorem' id='tcolobox-1'>   <a id='x1-3x'></a><a id='x1-3xdoc'></a> 
<div class='tcolorbox-title'>
<!-- l. 12 --><p class='indent'>    1</p></div> 
<div class='tcolorbox-content'><!-- l. 11 --><p class='noindent'>Text</p>                                                                                                  
</div> 
</div>
   <div class='tcolorbox theorem' id='tcolobox-2'>   <a id='x1-5x'></a><a id='x1-5xdoc'></a> 
<div class='tcolorbox-title'>
<!-- l. 16 --><p class='indent'>    2</p></div> 
<div class='tcolorbox-content'><!-- l. 15 --><p class='noindent'>Text</p>                                                                                                  
</div> 
</div>
<!-- l. 18 --><p class='noindent'>See <a href='#x1-3xdoc'>theorem 1</a> and <a href='#x1-5xdoc'>theorem 2</a>
</p>

And rendered HTML:

enter image description here

2
  • Thanks! Now every environment has a unique link destination. However, there is still an issue with multiple environments defined by tcolorbox. I'll update the question to make it clearer.
    – user44413
    Nov 24, 2021 at 8:20
  • @user44413 ah, you are right. I forgot to erase the label after use.
    – michal.h21
    Nov 24, 2021 at 13:24

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.