I am trying to create a caption command that highlights the first sentence and also uses the first sentence as a short caption for the table of *.
Let's call it kaption
.
This is done using the listofitems
package to split the caption of a figure/table/listing based on dots.
This works but in combination with cleveref, cleveref is unable to generate the correct reference and instead uses the label of the current hierarchy (eg section).
Why is cleveref unable to find the correct reference? And how can I fix this?
Manually altering the captions is not a viable solution as my book has more than 100 images and tables, thus, I want to use a somehow automatic way.
MWE:
\documentclass{article}
\usepackage{cleveref}
\usepackage{graphicx}
\usepackage{ifthen}
\usepackage{listofitems}
\newcommand*{\kaption}[1]{
\setsepchar{.}\readlist*\pdots{#1}{
\caption[{\pdots[1]}]
{%
\foreachitem\sentence\in\pdots{
\ifnum \sentencecnt = 1
{\textbf{\pdots[\sentencecnt].}}
\else
{\pdots[\sentencecnt]\pdotssep[\sentencecnt]}
\fi
}}
}
}
\begin{document}
\section{With caption}
Reference fig 1 before: \cref{fig1}
\begin{figure}[h]
\centering
\includegraphics[height=2cm]{example-image-a}
\caption{Caption with one sentence. And another sentence of course.}
\label{fig1}
\end{figure}
Reference fig 1 after: \cref{fig1}
\section{With kaption}
Reference fig 2 before: \cref{fig2}
\begin{figure}[h]
\centering
\includegraphics[height=2cm]{example-image-a}
\kaption{Caption with one sentence. And another sentence of course.}
\label{fig2}
\end{figure}
Reference fig 2 after: \cref{fig2}
\end{document}
Best Answer
The issue you've encountered is not limited to
\cref
: it crops up with the basic\ref
macro as well.@daleif has already identified the issue: The
\readlist*\pdots{#1}{...}
material forms a group, and what's inside that group is not visible to the\label
instruction. The only thing that LaTeX can do in this situation is to associate the argument of\label
with the most recently incremented visible counter, which happens to be thesection
counter. Not good.A klugdy fix would be to change
to
If you plan to apply
\kaption
totable
environments as well, you'll also need to create a separate macro -- called, say,\kaptiont
-- just for tables. As I said, it's a kludge.A non-kludgy solution is available if you are free to use LuaLaTeX to compile your document: the creation of a Lua function that modifies all instances of
\caption{First. Last.}
automatically to\caption[First.]{\textbf{First.} Last.}
. To achieve this setup, it's necessary to assign this function to LuaTeX'sprocess_input_buffer
callback, so that it may act as a preprocessor on the input material, before TeX starts its usual processing.Whitespace between
\caption
and its argument is allowed. If there's just one sentence in the caption, the entire caption is bolded in the body of the document. The only restrictive input requirement is that line breaks are not allowed either in the argument of\caption{ ... }
or between\caption
and its argument.