我正在嘗試實現該命令的自訂版本\ref
。我發現為了能夠重新定義這個命令,我需要透過這樣做,\AtBeginDocument
否則我的更改似乎會被其他東西覆蓋。
現在它可以按預期工作,除非\ref
在 a 內部使用時\caption
會產生以下錯誤:
Argument of \@caption has an extra }. \caption{Test here \ref{sec:Section}}
Paragraph ended before \@caption was complete. \caption{Test here \ref{sec:Section}}
這是重現問題的 MWE:
\documentclass{article}
\usepackage{xstring}
\AtBeginDocument{%
\let\refCopy\ref
\renewcommand{\ref}[1]{%
\IfBeginWith{#1}{eq:}{
(\refCopy{#1})
}{
\refCopy{#1}
}
}
}
\setcounter{errorcontextlines}{999}
\begin{document}
\section{Section}
\label{sec:Section}
\begin{figure}
\caption{Test here \ref{sec:Section}}
\end{figure}
\end{document}
\ref
如果我刪除文檔 的自訂實現,編譯就可以了。
是什麼導致了這個問題以及如何避免它?
答案1
您的(重新)定義\ref
使其成為所謂的“脆弱”命令。如果在「移動命令」的參數中使用這一點\ref
,例如\caption
.你需要改變
\caption{Test here \ref{sec:Section}}
到
\caption{Test here \protect\ref{sec:Section}}
此外,您需要確保在交叉引用呼叫之前或之後沒有引入虛假空格。我建議你改變
\renewcommand{\ref}[1]{%
\IfBeginWith{#1}{eq:}{
(\refCopy{#1})
}{
\refCopy{#1}
}
}
到
\renewcommand{\ref}[1]{%
\IfBeginWith{#1}{eq:}{%
(\refCopy{#1})%
}{%
\refCopy{#1}%
}%
}%
你能發現 的六個新實例嗎%
?
附錄:正如 @AlanMunn 在評論中指出的那樣,如果加載包並替換為 ,\protect
則不需要這些指令。etoolbox
\renewcommand{\ref}...
\renewrobustcmd{\ref}...
將程式碼格式設定為
\renewcommand{\ref}[1]{%
\IfBeginWith{#1}{eq:}{%
(\refCopy{#1})%
}{%
\refCopy{#1}%
}%
}%
可能會使其更具可讀性,因為等級更明顯。