This solution doesn't rely on the caption
package and is able to dynamically change the appearence of \figurename
and \tablename
.
(As it uses the internal \@captype
(that expands in our cases to figure
or table
), it should work in other environments, that define a caption, too).
Explanation
letltxmacro
: saving the definition of \caption
At first we backup the original definition of \caption[<list>]{<caption>}
to \ocaption
.
xparse
: defining the new \caption
Then we declare the new command: \caption[<color>]{<pre>}[<list>]{<caption>}
<color>
(optional, default black
): The color in which (<pre>)
appears. If <pre>
is empty, <color>
is simply ignored.
<pre>
: The prefix that appears in <color>
and surrounded by ()
. If it's empty than the ()
are omitted.
<list>
(optional): behaves like the original optional argument of \caption
.
<caption>
etoolbox
: (code)
goes where?
As egreg pointed out in the commands, because \figurename
, \tablename
and so on will most likely not use a parameter, there's no need to use \pretocmd
.
These patch-lines can even be shorten further when we use \cspreto{\@captype name}{…}
instead of \expandafter\preto\csname\@captype name\endcsname{…}
.
\ocaption
: the caption
The last line of the new \caption
command uses the old \caption
definition (now saved in \ocaption
) to finally deal with the caption.
Notes
I used \llap
to typeset (code)
so that it doesn't change the horizontal alignment of the caption (compare captions 1 and 2). If you don't want this behavior, see code comments.
You still can use \ocaption[<list>]{<caption>}
to use the original definition. But you can use the new \caption{}[<list>]{<caption>}
with an empty second argument to get the same behavior.
You may define your own command if you need to use (R)
or (D)
repeatedly:
\newcommand{\Rcaption}[2][]{%
\ifx\\#1\\%
\caption[red]R{#2}%
\else%
\caption[red]R[#1]{#2}%
\fi%
}
If you rather rarely will use the new \caption
command and often use your own \Rcaption
commands, you don't have to redefine \caption
and instead define an improved \newcaption
. See section “Code (unchanged \caption
)”!
Code (changed \caption
)
\documentclass{article}
\usepackage{xcolor}
\usepackage{xparse}
\usepackage{letltxmacro}
\usepackage{etoolbox}
\makeatletter
\LetLtxMacro{\ocaption}{\caption}
\DeclareDocumentCommand{\caption}{O{black}mO{}m}{% #1 = color for added #2
% #2 = text to appear in front of Figure, Table, ...
% #3 = caption for list
% #4 = caption
{% keep changes local!
\ifx\\#2\\\else%
\cspreto{\@captype name}{\ifvmode\textcolor{#1}{(#2)}~\else\llap{\textcolor{#1}{(#2)}~}\fi}{}{}% (with \llap)
% \cspreto{\@captype name}{\textcolor{#1}{(#2)}~}{}{}% (without \llap)
\fi%
\ifx\\#3\\\ocaption{#4}\else\ocaption[#3]{#4}\fi%
}%
}
\makeatother
\newcommand{\Rcaption}[2][]{%
\ifx\\#1\\%
\caption[red]R{#2}%
\else%
\caption[red]R[#1]{#2}%
\fi%
}
\newcommand{\Dcaption}[2][]{%
\ifx\\#1\\%
\caption[blue]D{#2}%
\else%
\caption[blue]D[#1]{#2}%
\fi%
}
\begin{document}
\listoffigures
\listoftables
\hrulefill
\begin{figure}[!ht]
\Rcaption{Caption 1}
\end{figure}
\begin{figure}[!ht]
\caption{}{Caption 2}
\end{figure}
\begin{figure}[!ht]
\Dcaption[Caption 3]{Caption 3 but longer}
\end{figure}
\hrulefill
\begin{table}[!ht]
\Rcaption{Caption 4}
\end{table}
\begin{table}[!ht]
\caption[green]{A}{Caption 5}
\end{table}
\begin{table}[!ht]
\Dcaption[Caption 6 \textcolor{blue}{(D)}]{Caption 6 --- but much more longer so that it spans over one line. You can see now, that \textcolor{blue}{(D)} does not appear in the margin.}
\end{table}
Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo.
\end{document}
Code (unchanged \caption
)
\documentclass{article}
\usepackage{xcolor}
\usepackage{xparse}
\usepackage{etoolbox}
\makeatletter
\DeclareDocumentCommand{\newcaption}{O{black}mO{}m}{% #1 = color for added #2
% #2 = text to appear in front of Figure, Table, ...
% #3 = caption for list
% #4 = caption
{% keep changes local!
\ifx\\#2\\\else%
\cspreto{\@captype name}{\ifvmode\textcolor{#1}{(#2)}~\else\llap{\textcolor{#1}{(#2)}~}\fi}{}{}% (with \llap)
% \cspreto{\@captype name}{\textcolor{#1}{(#2)}~}{}{}% (without \llap)
\fi%
\ifx\\#3\\\caption{#4}\else\caption[#3]{#4}\fi%
}%
}
\makeatother
\newcommand{\Rcaption}[2][]{%
\ifx\\#1\\%
\newcaption[red]R{#2}%
\else%
\newcaption[red]R[#1]{#2}%
\fi%
}
\newcommand{\Dcaption}[2][]{%
\ifx\\#1\\%
\newcaption[blue]D{#2}%
\else%
\newcaption[blue]D[#1]{#2}%
\fi%
}
\begin{document}
\listoffigures
\listoftables
\hrulefill
\begin{figure}[!ht]
\Rcaption{Caption 1}
\end{figure}
\begin{figure}[!ht]
\caption{Caption 2}
\end{figure}
\begin{figure}[!ht]
\Dcaption[Caption 3]{Caption 3 but longer}
\end{figure}
\hrulefill
\begin{table}[!ht]
\Rcaption{Caption 4}
\end{table}
\begin{table}[!ht]
\newcaption[green]{A}{Caption 5}
\end{table}
\begin{table}[!ht]
\Dcaption[Caption 6 \textcolor{blue}{(D)}]{Caption 6 --- but much more longer so that it spans over one line. You can see now, that \textcolor{blue}{(D)} does not appear in the margin.}
\end{table}
Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo.
\end{document}
Output (both cases)

(code)
fragments appear in the Lists of Tables and Figures in some way automatically?