Почему следующее выражение 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 **
Обобщенный ответ
Похожий подход без использования \@tempswa
and можно использовать для других псевдоусловий LaTeX, таких как \@ifpackageloaded
or \@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. Также можно указать код для ветви false.
Альтернативный метод
В качестве альтернативы используйте 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}