\apptocmd in eine Bedingung umwandeln – warum funktioniert das nicht?

\apptocmd in eine Bedingung umwandeln – warum funktioniert das nicht?

Warum funktioniert das folgende MWE nicht, obwohl es funktioniert, wenn ich die Bedingung kommentiere?

\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}

Antwort1

Hauptantwort

Im Allgemeinen #kann das Patchen von Befehlen, wenn beteiligt ist, nicht im Argument eines anderen Befehls erfolgen. Man kann einige Tricks mit Kategoriecodes machen, aber ein anderer Ansatz kann einfacher sein:

\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}

Die \if@tempswaBedingung ist eine vom Kernel bereitgestellte Scratch-Bedingung.

Folgendes steht in der .logDatei:

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

Allgemeine Antwort

Ein ähnlicher Ansatz ohne Verwendung von \@tempswaund, der für andere LaTeX-Pseudokonditionale wie \@ifpackageloadedoder verwendet werden kann \@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

Dies beruht auf der Tatsache, dass \ifToken erweitert werden und dass LaTeX-Pseudokonditionale vollständig erweiterbar sind; am Ende wird also \ifentweder gefunden 11, ob die Bedingung erfüllt ist, oder andernfalls 01, und es werden die Zweige „true“ und „false“ entsprechend befolgt. Beachten Sie, dass solche Konstruktionen in andere Konditionale im TeX-Stil verschachtelt werden können. Code für den Zweig „false“ kann ebenfalls angegeben werden.

Alternative Methode

Alternativ verwenden Sie das regexpatchPaket:

\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}

verwandte Informationen