在使用 \iffoo 之前测试它是否已定义

在使用 \iffoo 之前测试它是否已定义

tikz在非平凡文档中 使用时,该库external是必要的,以使 PDF 构建时间可接受(除非为每个图形制作单独的 TikZ PDF)。

不幸的是,这个库有很多错误,例如不能与 Beamer 叠加层配合使用。有修复方法,例如

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

由于该命令,TikZ 图片具有覆盖,\pause并且由于\tikzset{...}修复,输出已正确生成。

我想将此命令.sty与其他通用 hack 一起放在单独的文件中。当然,如果我从非 Beamer 文档加载样式文件,\ifbeamer@anotherslide则将未定义。所以我需要使命令\tikzset{...}以 Beamer 类加载和/或\ifbeamer@anotherslide 定义为条件。我尝试了以下几种方法:

%%% 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

然而,像这样的结构:

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

都是违法的。

如何才能让\tikzset上述命令仅在必要时运行,即当 Beamer 文档使用覆盖时运行,而当使用其他类型的文档时则不运行?

答案1

对于一般用例,您可以使用\@ifclassloaded{beamer}{<code for beamer>}{<code for other classes>}它来测试当前类。

如果你的非 Beamer 文档恰好使用了该beamerarticle包,你也可以使用模式进行测试,例如\mode<beamer>{code for beamer class}(参见https://tex.stackexchange.com/a/657316/36296例如)。


与问题无关,但我不会\pause在 tikzpicture 中使用,这可能会产生各种“有趣”的副作用,例如使脚线消失。相反,要么使用 tikz 节点的覆盖感知,要么查看overlay-beamer-stylestikz 库。

% !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}

答案2

这是解决你的问题的方法\iffoo:这个想法是绝不使用\iffoo,因此 TeX 永远不会“看到”条件。

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

在此处输入图片描述

您可能还想定义\BooleanExistsF\BooleanT\BooleanF

相关内容