5

When using tikz in a non-trivial document, the library external is necessary to make PDF build time acceptable (unless one makes a separate TikZ PDF for each figure).

Unfortunately, this library has a number of bugs, such as not working with Beamer overlays. There are fixes, such as this:

\documentclass{beamer}
  \usepackage{tikz}
  \usetikzlibrary{external}
  \tikzexternalize
\makeatletter
\ifdefined\ifbeamer@anotherslide  
\tikzset{
  beamer externalising/.style={%
    execute at end picture={%
      \tikzifexternalizing{%
        \ifbeamer@anotherslide
          \pgfexternalstorecommand{\string\global\string\beamer@anotherslidetrue}%
        \fi
      }{}%
    }%
  }, external/optimize=false, every picture/.style={beamer externalising}
}
\fi
\makeatother

\begin{document} \begin{frame} \begin{tikzpicture} \node {A\qquad\ }; \pause \node {B}; \end{tikzpicture} \end{frame} \end{document}

The TikZ picture has an overlay, due to the \pause command, and the output is properly generated because of the \tikzset{...} fix.

I would like to put this command in a separate .sty file, together with other general purpose hacks. Of course, if I loaded the style file from a non-Beamer document, \ifbeamer@anotherslide would be undefined. So I need to make the \tikzset{...} command conditional to the Beamer class loading and/or \ifbeamer@anotherslide being defined. I tried several things along these lines:

%%% hack.sty
\ifdefined\ifbeamer@anotherslide  
  \tikzset{
    beamer externalising/.style={%
      execute at end picture={%
        \tikzifexternalizing{%
          \ifbeamer@anotherslide
            \pgfexternalstorecommand{\string\global\string\beamer@anotherslidetrue}%
          \fi
        }{}%
      }}, external/optimize=false, every picture/.style={beamer externalising}
  }
\fi

However, constructs like:

\ifdefined\iffoo
 \iffoo
   % do stuff
 \fi
\fi

are illegal.

How can I have the \tikzset command above to be run only when it is necessary, that is, when there is a Beamer document using overlays, and not when other types of documents are used?

antonio
  • 1,446

2 Answers2

4

For a general use case, you can use \@ifclassloaded{beamer}{<code for beamer>}{<code for other classes>} to test for the current class.

In case your non-beamer documents happen to use the beamerarticle package, you could also test with modes, e.g. \mode<beamer>{code for beamer class} (see https://tex.stackexchange.com/a/657316/36296 for an example).


Unrelated to the question, but I wouldn't use \pause inside a tikzpicture, this can have all kinds of "funny" side effects, like making footlines disappear. Instead either use the overlay awareness of tikz nodes or have a look at the overlay-beamer-styles tikz library.

% !TeX program = txs:///arara
% arara: pdflatex: {synctex: on, interaction: nonstopmode, shell: yes}

\documentclass{beamer} \usepackage{tikz} \usetikzlibrary{external} \tikzexternalize \makeatletter @ifclassloaded{beamer}{ \ifdefined\ifbeamer@anotherslide
\tikzset{ beamer externalising/.style={% execute at end picture={% \tikzifexternalizing{% \ifbeamer@anotherslide \pgfexternalstorecommand{\string\global\string\beamer@anotherslidetrue}% \fi }{}% }% }, external/optimize=false, every picture/.style={beamer externalising} } \fi }{} \makeatother

\begin{document} \begin{frame} \begin{tikzpicture} \node<+-> {A\qquad\ }; \node<+-> {B}; \end{tikzpicture} \end{frame} \end{document}

3

Here's a way out for your \iffoo problem: the idea is to never use \iffoo, so TeX will never “see” conditionals.

\documentclass{article}

\ExplSyntaxOn

\NewExpandableDocumentCommand{\BooleanExistsTF}{mmm} { \cs_if_exist:cTF { if#1 } { #2 } { #3 } }

\NewExpandableDocumentCommand{\BooleanExistsT}{mm} { \cs_if_exist:cT { if#1 } { #2 } }

\NewExpandableDocumentCommand{\BooleanTF}{mmm} { \legacy_if:nTF { #1 } { #2 } { #3 } }

\ExplSyntaxOff

\begin{document}

\BooleanExistsTF{foo}{% \BooleanTF{foo}{YES}{NO}% }{DOESN'T EXIST}

\newif\iffoo

\BooleanExistsT{foo}{% \BooleanTF{foo}{YES}{NO}% }

\footrue

\BooleanExistsT{foo}{% \BooleanTF{foo}{YES}{NO}% }

\end{document}

enter image description here

You may want to define also \BooleanExistsF, \BooleanT or \BooleanF.

egreg
  • 1,121,712