\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 伪条件,例如\@ifpackageloadedor \@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

这依赖于扩展标记和 LaTeX 伪条件完全可扩展的事实\if;因此最终\if会发现11如果条件为真,则为真,否则为假01,因此它会相应地遵循真和假分支。请注意,此类构造可以嵌套在其他 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}

相关内容