
我正在嘗試自動轉換\caption{...\label{...}...}
為\caption{...}\label{...}
.這是我嘗試過的:
\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}
pdf 文件看起來也正確,但我收到此錯誤訊息(五次,每次調用一次\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 ##.
如果我替換\storelabel{##1}
為\storelabel{mylabel}
,pdf 文件看起來是一樣的,並且錯誤訊息消失了。但這顯然不是我想要的。
更新:這個 MWE 很好地顯示了同樣的錯誤,雖然這與我最初的目標無關,即\label
搬出\caption
並搬走showlabels
唱片公司。
\documentclass{article}
\begin{document}
\begin{table}
\caption{\def\foo[#1]{#1}}
\end{table}
\end{document}
答案1
在我看來,最好捕獲 the\label
並讓它將標籤名稱存儲到\storedlabel
in 中\caption
,然後在發布後將實際值轉移到 ,\label
的末尾。\@caption
\@makecaption
重新定義\label
willbreakcleveref
風格\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}
答案2
這有效:
\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}
主要區別是
\def\label##1{...}
->\let\label\storelabel
,避免使用##1
內部參數\caption
- 受到 @ChristianHupfer 的啟發和感謝,使用 來
xpatch
選擇性地修補\@caption
而不是重新定義\caption
.它甚至可以與caption
package 和\listoftables
now 一起使用。
他的評論仍然成立:\label
可選參數失敗。但我不需要那個。