Open dbitouze opened 4 months ago
When hyperref
is not loaded (more precisely when \phantomsection
is not defined), /tcb/phantomlabel
and /tcb/label
behave exactly the same.
But when hyperref
is loaded, /tcb/phantomlabel
uses \phantomsection
to insert an anchor (hyperlink destination) using a special counter section*
, which stands for things like unnumbered sections.
So if one uses /tcb/phantomlabel
on a numbered box with hyperref
loaded, that label will be partially bound to a wrong counter section*
, instead of the actual counter used by that box.
In your example, adding
\makeatletter
\newcommand{\tcb@cnt@examplename}{Example}
\makeatother
to provide the description label for \autoref
and then check outputs of \autoref{<label>}
, you'll find the output \autoref{bar}
wrong. Expected output is Example 2
, but instead you'll get Section 2
, "description of dummy counter section*
" + "value of real counter \tcb@cnt@example
".
Check out the relevant lines in .aux
file
\newlabel{foo}{{1}{2}{}{tcb@cnt@example.1}{}} % expected form for numbered boxes
\newlabel{bar}{{2}{3}{}{section*.1}{}} % WRONG form (for numbered boxes)
\newlabel{baz}{{1}{4}{Unnumbered}{section*.2}{}} % expected form for unnumbered boxes
\autoref
example```tex \documentclass{article} \usepackage{tcolorbox} \usepackage{hyperref} \NewTColorBox[auto counter]{example}{+O{}}{ title=Numbered Example~\thetcbcounter, #1 } \NewTColorBox{example*}{+O{}}{ title=Unumbered Example, #1 } \makeatletter \newcommand{\tcb@cnt@examplename}{Example} \makeatother \begin{document} \begin{itemize} \item See numbered examples: \begin{itemize} \item \ref{foo} on page~\pageref{foo}, \autoref{foo} \item \ref{bar} on page~\pageref{bar}, \autoref{bar}. \end{itemize} \item See unnumbered example on page~\pageref{baz}, \autoref{baz}. \end{itemize} \newpage \begin{example}[label=foo] Foo \end{example} \newpage \begin{example}[phantomlabel=bar] Bar \end{example} \newpage \section{Unnumbered} \begin{example*}[phantomlabel=baz] Baz \end{example*} \end{document} ```
If it's possible to detect whether a box is numbered, then /tcb/label
could be improved to cover /tcb/phantomlabel
, like
# /tcb/label=<label>
if (this_box.numbered?):
return "\__tcobox_label:n {<label>}"
elif (cs_if_exist("\phantomsection")):
return "\phantomsection \__tcobox_label:n {<label>}"
else:
raise Error # or warning
To cover the cases when a box counter is stepped by user, not by options like /tcb/new/auto counter
, one possible option would be to check if \@currentlabel
changes between /tcb/before
and \__tcobox_label:n
.
The idea to detect automatically if \phantomsection
is needed is interesting. A test on \@currentlabel
changes between /tcb/before
and \__tcobox_label:n
does not work, because the code of /tcb/before
is executed afterwards, but one could check \@currentlabel
changes from before phantom
is used.
However, I see several problems.
tcolorbox
is inserted. I think, I have no such application, but others may have.\@currentlabel
does not necessarily change for numbered boxes. If you insert a \section{Example}
at begin of your document, the \@currentlabel
is 1
and stays 1
for the first box (which also has the number 1). This could be solved by inserting a boolean marker for automatically numbered boxes, but will give a serious and spurious fail for boxes numbered manually by a user. Here, spurious \phantomsection
's will be inserted whenever \@currentlabel
does not change for a manually numbered box.If no fail-save test (how?) is possible, I rather stay with the current implementation. After all, the usage is quite clear:
label
for anyhow numbered boxes.phantomlabel
for unnumbered boxes.If no fail-save test (how?) is possible, I rather stay with the current implementation. After all, the usage is quite clear:
- use
label
for anyhow numbered boxes.- use
phantomlabel
for unnumbered boxes.
Agreed. Maybe the manual could be more clear about this.
As pointed out by the following MCE,
phantomlabel
can be used just aslabel
is:Therefore, wouldn't it be possible to make
label
simply bephantomlabel
(and save the user having to decide which oflabel
andphantomlabel
to use)?