1

(This is a follow-up of the (unfortunately closed) question Is there a way to change the style of a float depending on whether it is on the same page of call out or not?))

In order to change the style of a float depending on whether it is on the same page of call out or not, I tried to implement the David's suggestion:

set a label,then check the \pageref with the current page and fix up the typesetting on the next run if they are the same

(AFAICS, I have to resort to refcount's \getpagerefnumber since it is not possible to directly compare the \thepage with the string \pageref{...}, but the problem I encounter arises with the two.)

But it seems to be an issue with this approach: in the following MCE, both the call out page (theoretically given by the current page counter \thepage) and the displayed page (given by both \pageref{...} and \getpagerefnumber{...}) of the (second) float is the page 2 but \thepage tells it is page 1.

OK, \thepage is known for always giving the right number. So the question remains: is there a way to change the style of a float depending on whether it is on the same page of call out or not?

\documentclass{article}
\usepackage{refcount}
\usepackage{mwe}

\AddToHook{env/figure/end}{ \caption{The nice figure #\thefigure{} (% thepage: \thepage, pageref: \pageref{ex-\thefigure}, getpagerefnumber: \getpagerefnumber{ex-\thefigure}% )% } \label{ex-\thefigure} } \begin{document} \begin{figure}[htb] \centering \includegraphics[width=.5\linewidth]{example-image-a} \end{figure}

\begin{itemize} \item Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus eu tellus sit amet tortor gravida placerat. In- teger sapien est, iaculis in, pretium quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean faucibus. Morbi dolor nulla, male- suada eu, pulvinar at, mollis ac, nulla. Curabitur auctor semper nulla. Donec varius orci eget risus. Duis nibh mi, congue eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim rutrum. \item Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus eu tellus sit amet tortor gravida placerat. In- teger sapien est, iaculis in, pretium quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean faucibus. Morbi dolor nulla, male- suada eu, pulvinar at, mollis ac, nulla. Curabitur auctor semper nulla. Donec varius orci eget risus. Duis nibh mi, congue eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim rutrum.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra metus rhoncus sem. Nulla et lectus vestibulum urna \item Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus eu tellus sit amet tortor gravida placerat. In- teger sapien est, iaculis in, pretium quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean faucibus. Morbi dolor nulla, male- suada eu, pulvinar at, mollis ac, nulla. Curabitur auctor semper nulla. Donec varius orci eget risus. Duis nibh mi, congue eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim rutrum. \begin{figure}[htb] \centering \includegraphics[width=.5\linewidth]{example-image-b} \end{figure} \end{itemize} \end{document}

enter image description here

Denis Bitouzé
  • 9,652
  • 4
  • 27
  • 85
  • \thepage is only expected to get correct value at shipout. egreg says as much in the link you provided: "You can rely upon the value of \thepage only immediately after a \newpage command". – gusbrs Mar 15 '22 at 10:55
  • On the main question, you say you'd like to change the style of the float depending on whether it is on the same page of the callout. But you are trying to identify the condition by comparing \thepage to \getpagerefnumber{ex-\thefigure} (if I understood correctly). In neither MCE of this question or the original question the "callout" appears. As far as I can tell, you need two labels, one at the float and another at the "callout", and then you can compare pageref's of both. You may or may not need \getpagerefnumber, depending on the test you want to make. ... – gusbrs Mar 15 '22 at 11:06
  • ... You need it to compare the numbers, but you might as well just compare equality. – gusbrs Mar 15 '22 at 11:06
  • I correct myself, we do need \getpagerefnumber regardless, since \pageref is not expandable, so we cannot retrieve its value for comparison. – gusbrs Mar 15 '22 at 11:59

2 Answers2

1

This is an attempt on the task. You say you'd like to change the style of the float depending on whether it is on the same page of the callout. But in neither MCE of this question or the original question the "callout" appears. As far as I can tell, you need two labels, one at the float and another at the "callout", and then you can compare pageref's of both.

I did not use the env/figure/end hook, since as it is it would require that we know \thefigure when making the callout. I preferred to use a label, as usual, but in this simple implementation, this involves restating the label for the conditional \IfOnTheSamePage, so there's a little repetition. It still seems reasonable, and it is at least a proof of concept.

\documentclass{article}
\usepackage{refcount}
\usepackage{mwe}

\newcounter{dbcallout} \NewDocumentCommand\dbcallout{m} {% \refstepcounter{dbcallout}% \label{callout-#1}% callout~\ref{#1}% } \ExplSyntaxOn \prg_new_protected_conditional:Npnn __db_if_on_same_page:n #1 { TF } { \group_begin: \tl_if_exist:cTF { r@ #1 } { \tl_set:Nx \l_tmpa_tl { \getpagerefnumber {#1} } } { \tl_clear:N \l_tmpa_tl } \tl_if_exist:cTF { r@ callout - #1 } { \tl_set:Nx \l_tmpb_tl { \getpagerefnumber { callout - #1 } } } { \tl_clear:N \l_tmpb_tl } \tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl { \tl_if_empty:NTF \l_tmpa_tl { \group_insert_after:N \prg_return_false: } { \group_insert_after:N \prg_return_true: } } { \group_insert_after:N \prg_return_false: } \group_end: } \NewDocumentCommand \IfOnTheSamePage { m m m } { __db_if_on_same_page:nTF {#1} {#2} {#3} } \ExplSyntaxOff

\begin{document} \begin{figure}[htb] \caption{% \IfOnTheSamePage{fig:1}{\bfseries}{}% Caption% } \label{fig:1} \centering \includegraphics[width=.5\linewidth]{example-image-a} \end{figure}

\dbcallout{fig:1}

\dbcallout{fig:2}

\begin{itemize} \item \lipsum[1] \item \lipsum[2-3] \item \lipsum[4] \begin{figure}[htb] \caption{% \IfOnTheSamePage{fig:2}{\bfseries}{}% Caption% } \label{fig:2} \centering \includegraphics[width=.5\linewidth]{example-image-b} \end{figure} \end{itemize} \end{document}

enter image description here


enter image description here

Of course, the above checks whether the callout starts on the same page as the float. If you'd like to check whether the callout starts and ends on the same page, you'd have to add a third label at the end of the callout and compare the three of them (similar to what varioref does to verify if a reference crosses a page boundary).

gusbrs
  • 13,740
  • Works well: thanks! But I should have explained further the context and I probably oversimplified the example: sorry for that. In fact, I used env/figure/end since I want to "hack" an existing environment (namely a tcolorbox's \DeclareTCBListing equipped with a float option, with the automatic numbering and with a hidden automatic label used behind the scene for the current purpose) in order to/and no specific action from the user is required. If I understand well your solution, the user has to insert systematic \dbcallout{⟨label⟩} commands and has to know this ⟨label⟩. – Denis Bitouzé Mar 16 '22 at 14:56
  • @DenisBitouzé Well, yes, I can only work with what you gave us... I hope it is enough for you to adjust for your actual use case. Regarding \dbcallout, yes, it must be called somewhere somehow. And one should know the label (better than having to know the figure counter number). What else might be a "call out" if not a reference to the float? (You tell me, since you omitted it in the question, I had to guess). In other words, what is it that you want to check "if it is on the same page as the float". It must be something else, since we already know the float is on the same page as itself. – gusbrs Mar 16 '22 at 15:18
  • I guess I could manage, using this trick from Heiko Oberdiek and ideas from your solution. Will post an answer soon. – Denis Bitouzé Mar 16 '22 at 16:32
  • @DenisBitouzé Ah! So it appears that what you wanted after all is to check if the float has been displaced from the page it appears in the source. I wouldn't have ever dreamt of calling this "callout", no wonder I didn't understand what you wanted. Anyway, I'm glad you found a solution. – gusbrs Mar 16 '22 at 19:10
  • Sorry for my translation error that led to this misunderstanding! If you have a suggestion, it would welcome. – Denis Bitouzé Mar 16 '22 at 19:54
  • 1
    @DenisBitouzé No problem, English is lingua franca, but not the first language of most people we interact with (not mine either). So, it happens ;-). – gusbrs Mar 16 '22 at 20:02
0

Finally, I guess I could manage to find a solution with the help of this trick from Heiko Oberdiek and ideas from gusbrs answer.

\documentclass{article}
\usepackage{refcount}
\usepackage{mwe}
\usepackage{xcolor}

\ExplSyntaxOn \int_new:N \g__call_out_label_int \str_new:N \g__call_out_label_str

\AddToHook{env/figure/before}{ \leavevmode \int_incr:N \g__call_out_label_int \str_set:Nx \g__call_out_label_str {call_out_label:\int_use:N \g__call_out_label_int} \label{\g__call_out_label_str} } \AddToHook{env/figure/end}{ \caption{% \tl_set:Nx \l_tmpa_tl { \getpagerefnumber {\g__call_out_label_str} } \tl_set:Nx \l_tmpb_tl { \getpagerefnumber {ex-\thefigure} } \tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl { \color{blue} Float~ on~ the~ same~ page~ as~ its~ call-out~ point }{ \color{red} Float~ NOT~ on~ the~ same~ page~ as~ its~ call-out~ point } } \label{ex-\thefigure} } \ExplSyntaxOff \begin{document} \begin{figure}[htb] \centering \includegraphics[width=.5\linewidth]{example-image-a} \end{figure}

\lipsum[1-2]

\begin{figure}[htb] \centering \includegraphics[width=.5\linewidth]{example-image-b} \end{figure} \end{document}

enter image description here

Denis Bitouzé
  • 9,652
  • 4
  • 27
  • 85