I am trying to automatically convert \caption{...\label{...}...} to \caption{...}\label{...}. This is what I have tried:
\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}
The pdf file looks correct, too, but I get this error message (five times, once per call of \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 ##.
If I replace \storelabel{##1} by \storelabel{mylabel}, the pdf file looks the same and the error message is gone. But this is not what I want, obviously.
Update: This MWE nicely shows the same error, although it is unrelated to my original goal of moving \label out of \caption and thereby moving the showlabels labels.
\documentclass{article}
\begin{document}
\begin{table}
\caption{\def\foo[#1]{#1}}
\end{table}
\end{document}

\captionhas an (moving) optional argument which gets lost here -- I fear that your approach screws up the whole labelling system – Mar 24 '16 at 18:03sedto make the changes in fact? (Aside from the fun the intellectual challenge may provide, for actual documents, it may be better to subscribe to the philosophy that just because TeX can do something doesn't mean you should use TeX to do it.) – jon Mar 24 '16 at 18:05\captionwith an argument -- it's in fact an moving argument. If thecaptionpackage` is loaded, those whole redefinitions would break again (even if they would work right now) – Mar 24 '16 at 18:06iopart, to be exact), which uses\labelinside\caption. @ChristianHupfer I agree for my particular application; but my redefinition of\captioncould be replaced by an appropriatexpatchcmdthat takes optional and moving arguments into account . Anyway, there seems to be something else I am doing wrong: look at the first short MWE, for example, where I reproduce the same error without any redefinition of\caption. It does not even have to involve\label, as the last short MEW now shows. – bers Mar 24 '16 at 18:33\def-ing `\protect? – jon Mar 24 '16 at 19:31\caption. I assume now, by the way, that this problem is mainly robustness (or lack thereof), and should simply be avoided as in my answer below: https://tex.stackexchange.com/questions/60353/are-commands-defined-by-newcommand-robust – bers Mar 24 '16 at 19:40iopart.cls. Although its guidelines tell us to put\labelin\caption, there is nothing in the class code that requires you to do so (and is 'wrong' from a LaTeX point of view -- see the LaTeX2e manual) unless you use the\Tablemacro. But that is a dirty hack that you should probably avoid anyway since it defines a table of 16 columns and then lets you input a table of fewer columns by relying on\\to prematurely end each row. – jon Mar 24 '16 at 20:01