\apptocmd 轉換為條件語句-為什麼它不起作用?

\apptocmd 轉換為條件語句-為什麼它不起作用?

為什麼下面的 MWE 不起作用,而如果我評論條件它就起作用?

\documentclass{beamer}

\makeatletter

\@ifclassloaded{beamer}{

\usepackage{bookmark}
\usepackage{etoolbox}

\apptocmd{\beamer@@frametitle}{\only<1>{\bookmark[page=\the\c@page,level=3]{#1}}}%
{\message{** patching of \string\beamer@@frametitle succeeded **}}%
{\message{** patching of \string\beamer@@frametitle failed **}}%

}{}

\makeatother


\begin{document}

\begin{frame}{Title}
Hello \pause world
\end{frame}
\end{document}

答案1

主要回答

一般來說,#涉及修補命令的情況不會發生在另一個命令的參數中。人們可以使用類別程式碼做一些技巧,但另一種方法可能更容易:

\documentclass{beamer}

\makeatletter
\@ifclassloaded{beamer}{\@tempswatrue}{\@tempswafalse}
\if@tempswa
  \usepackage{bookmark}
  \usepackage{etoolbox}
  \apptocmd{\beamer@@frametitle}
    {\only<1>{\bookmark[page=\the\c@page,level=3]{#1}}}%
    {\message{** patching of \noexpand\beamer@@frametitle succeeded **}}%
    {\message{** patching of \noexpand\beamer@@frametitle failed **}}%
\fi
\makeatother


\begin{document}

\begin{frame}{Title}
Hello \pause world
\end{frame}
\end{document}

\if@tempswa條件是核心提供的臨時條件。

文件中的內容如下.log

** patching of \beamer@@frametitle succeeded **

通用答案

不使用 and 的類似方法\@tempswa可用於其他 LaTeX 偽條件,例如\@ifpackageloaded\@ifundefined

\makeatletter
\newcommand{\latex@conditional}[1]{#1{11}{01}}

\if\latex@conditional{\@ifclassloaded{beamer}}
  \usepackage{bookmark}
  \usepackage{etoolbox}
  \apptocmd{\beamer@@frametitle}
    {\only<1>{\bookmark[page=\the\c@page,level=3]{#1}}}%
    {\message{** patching of \noexpand\beamer@@frametitle succeeded **}}%
    {\message{** patching of \noexpand\beamer@@frametitle failed **}}%
%\else
% code for the false branch
\fi
\makeatother

這依賴於擴展標記的事實\if以及 LaTeX 偽條件是完全可擴展的;所以最後\if會發現11如果條件為真,否則01會相應地遵循 true 和 false 分支。請注意,此類結構可以嵌套在其他 TeX 樣式條件中。也可以指定錯誤分支的程式碼。

替代方法

或者,使用該regexpatch套件:

\documentclass{beamer}

\makeatletter
\@ifclassloaded{beamer}{
  \usepackage{bookmark}
  \usepackage{regexpatch}
  \xapptocmd{\beamer@@frametitle}
    {\only<1>{\bookmark[page=\the\c@page,level=3]{#1}}}%
    {\message{** patching of \noexpand\beamer@@frametitle succeeded **}}%
    {\message{** patching of \noexpand\beamer@@frametitle failed **}}%
}{}
\makeatother


\begin{document}

\begin{frame}{Title}
Hello \pause world
\end{frame}
\end{document}

相關內容