\ref 的自訂定義會導致 \caption 參數內部出現問題

\ref 的自訂定義會導致 \caption 參數內部出現問題

我正在嘗試實現該命令的自訂版本\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}%
  }%
}%

可能會使其更具可讀性,因為等級更明顯。

相關內容