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?

2 Answers 2

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .