\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を使用しない同様のアプローチは、 or\@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

これは、トークンを展開し、LaTeX 疑似条件が完全に展開可能であるという事実に依存しています。\ifしたがって、最終的には条件が true の場合は 、そうでない場合は の\ifいずれかを見つけ、それに応じて true および false の分岐に従います。このような構造は、他の TeX スタイルの条件にネストできることに注意してください。false 分岐のコードも指定できます。1101

代替方法

あるいは、次の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}

関連情報