
Ich versuche, automatisch \caption{...\label{...}...}
in zu konvertieren \caption{...}\label{...}
. Folgendes habe ich versucht:
\documentclass{article}
\usepackage{showlabels}
\newcommand{\storelabel}[1]{\gdef\storedlabel{#1}}
\let\oldcaption\caption
\renewcommand{\caption}[1]{%
\let\storedlabel\undefined
\oldcaption{%
\def\label##1{%
\protect\storelabel{##1}%
}%
#1%
}%
\ifdefined\storedlabel%
\label{\storedlabel}%
\else%
\fi%
}
\begin{document}
\begin{table}
\caption{no label}
foo
\end{table}
\begin{table}
\caption{\label{mylabel}label inside caption (front)}
foo
\end{table}
\begin{table}
\caption{label inside caption (back) \label{mylabel}}
foo
\end{table}
\begin{table}
\caption{label directly after caption}
\label{mylabel}
foo
\end{table}
\begin{table}
\caption{label at end of table (I'm OK with that one)}
foo
\label{mylabel}
\end{table}
\end{document}
Die PDF-Datei sieht auch korrekt aus, aber ich erhalte diese Fehlermeldung (fünfmal, einmal pro Aufruf von \caption
):
! Illegal parameter number in definition of \reserved@a.
<to be read again>
1
l.20 \caption{no label}
You meant to type ## instead of #, right?
Or maybe a } was forgotten somewhere earlier, and things
are all screwed up? I'm going to assume that you meant ##.
Wenn ich \storelabel{##1}
durch ersetze \storelabel{mylabel}
, sieht die PDF-Datei genauso aus und die Fehlermeldung ist weg. Aber das ist natürlich nicht, was ich will.
Aktualisieren: Dieses MWE zeigt schön den gleichen Fehler,obwohl es nichts mit meinem ursprünglichen Ziel zu tun hat, \label
aus den Beschriftungen auszusteigen \caption
und sie dadurch zu verschiebenshowlabels
.
\documentclass{article}
\begin{document}
\begin{table}
\caption{\def\foo[#1]{#1}}
\end{table}
\end{document}
Antwort1
Meiner Ansicht nach ist es besser, das abzufangen \label
und den Beschriftungsnamen \storedlabel
in speichern zu lassen \caption
und dann den realen Wert \label
an das Ende von zu verschieben \@caption
, nachdem das \@makecaption
ausgegeben wurde.
Die Neudefinition von \label
Will Breaks cleveref
Stil \label[...]{foo}
!
\documentclass{article}
\usepackage{showlabels}
\usepackage{xparse}
\usepackage{letltxmacro}
\usepackage{xpatch}
\usepackage{cleveref} % Just for testing!
\makeatletter
\LetLtxMacro\latex@@origlabel\label
\xpatchcmd{%
\caption
}{%
\refstepcounter\@captype%
}{%
\let\storedlabel\undefined%
\refstepcounter\@captype
\begingroup
\renewcommand{\label}[1]{%
\gdef\storedlabel{##1}% Catch the the label but doing nothing except of storing it!
}
\endgroup
}{\typeout{Successfully patched caption}}{\typeout{Failed in patching caption}}
\xpatchcmd{\@caption}{%
\@makecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}\par
\endgroup}{%
\@makecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}\par
\endgroup%
\@ifundefined{storedlabel}{}{% Transfer the label to this place
\label@@origlabel{\storedlabel}}%
}{\typeout{Success}}{\typeout{Failure!}}
\makeatother
\begin{document}
\begin{table}
\caption{no label}
foo
\end{table}
\begin{table}
\caption{\label{othermylabel}label inside caption (front)}
foo
\end{table}
\begin{table}
\caption{label inside caption (back) \label{mylabel}}
foo
\end{table}
\begin{table}
\caption{label directly after caption}
\label{mylabelfoo}
foo
\end{table}
\begin{table}
\caption{label at end of table (I'm OK with that one)}
foo
\label{mylabelfoobar}
\end{table}
Now some referencing: \cref{othermylabel} and \ref{mylabel} and \ref{mylabelfoo} and \ref{mylabelfoobar}
\end{document}
Antwort2
Das funktioniert:
\documentclass{article}
%\usepackage{caption}
\usepackage{showlabels}
\usepackage{xpatch}
\def\storelabel#1{\gdef\storedlabel{#1}}
\makeatletter
\patchcmd{\@caption}{#3}{\global\let\storedlabel\undefined\let\label\storelabel#3}{}{err}
\apptocmd{\@caption}{\ifdefined\storedlabel\label{\storedlabel}\else\fi}{}{err}
\makeatother
\begin{document}
\listoftables
\clearpage
\begin{table}
\caption{no label}
foo
\end{table}
\begin{table}
\caption{\label{mylabel}label inside caption (front)}
foo
\end{table}
\begin{table}
\caption{label inside caption (back) \label{mylabel}}
foo
\end{table}
\begin{table}
\caption{label directly after caption}
\label{mylabel}
foo
\end{table}
\begin{table}
\caption{label at end of table (I'm OK with that one)}
foo
\label{mylabel}
\end{table}
\end{document}
Die Hauptunterschiede sind
\def\label##1{...}
->\let\label\storelabel
, wodurch die Verwendung des Arguments##1
innerhalb vermieden wird\caption
- Inspiriert von und dank @ChristianHupfer, die Verwendung von
xpatch
zum selektiven Patchen\@caption
statt Neudefinieren\caption
. Es funktioniert jetzt sogar mit demcaption
Paket und mit\listoftables
.
Sein Kommentar bleibt bestehen: \label
mit einem optionalen Argument schlägt es fehl. Aber das brauche ich nicht.