如何使用 ifdefined 来处理多个语句?

如何使用 ifdefined 来处理多个语句?

我想将两个ifdefined语句合并为一个语句。

\ifdefined\A
    blablablablablabla
\fi

\ifdefined\B
    blablablablablabla
\fi

那么,如何将这两者结合起来

\ifdefined\(A & B) % this macro is not correct
    blablablablablabla
\fi

或者

\ifdefined\(A or B) % this macro is not correct
    blablablablablabla
\fi

对此有什么想法吗?

答案1

\ifnum与正确构建的号码一起使用。

\ifnum\ifdefined\A 0\else 1\fi\ifdefined\B 0\else1\fi=0
  blabla
\else
  no
\fi

\def\A{}
\ifnum\ifdefined\A 0\else 1\fi\ifdefined\B 0\else1\fi=0
  blabla
\else
  no
\fi


\def\B{}
\ifnum\ifdefined\A 0\else 1\fi\ifdefined\B 0\else1\fi=0
  blabla
\else
  no
\fi

\bye

在此处输入图片描述

使用 LaTeX 和expl3

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewExpandableDocumentCommand{\bothdefinedTF}{mmmm}
 {
  \bool_lazy_and:nnTF { \cs_if_exist_p:N #1 } { \cs_if_exist_p:N #2 } { #3 } { #4 }
 }

\ExplSyntaxOff

\begin{document}

\bothdefinedTF{\A}{\B}{blabla}{no}

\def\A{}
\bothdefinedTF{\A}{\B}{blabla}{no}

\def\B{}
\bothdefinedTF{\A}{\B}{blabla}{no}

\end{document}

带有“或”的通用版本,以及带有任意数量的命令的“和”和“或”(这些命令较慢)。

\documentclass{article}
\usepackage{xparse}

\setlength{\parindent}{0pt} % just for the example

\ExplSyntaxOn

\NewExpandableDocumentCommand{\bothdefinedTF}{mmmm}
 {
  \bool_lazy_and:nnTF { \cs_if_exist_p:N #1 } { \cs_if_exist_p:N #2 } { #3 } { #4 }
 }

\NewExpandableDocumentCommand{\eitherdefinedTF}{mmmm}
 {
  \bool_lazy_or:nnTF { \cs_if_exist_p:N #1 } { \cs_if_exist_p:N #2 } { #3 } { #4 }
 }

\NewExpandableDocumentCommand{\alldefinedTF}{mmm}
 {
  \bool_if:nTF
   {
    \tl_map_function:nN { #1 } \__hokies_add_and:n \c_true_bool
   }
   { #2 } { #3 }
 }
\NewExpandableDocumentCommand{\onedefinedTF}{mmm}
 {
  \bool_if:nTF
   {
    \tl_map_function:nN { #1 } \__hokies_add_or:n \c_false_bool
   }
   { #2 } { #3 }
 }

\cs_new:Nn \__hokies_add_and:n { \cs_if_exist_p:N #1 && }
\cs_new:Nn \__hokies_add_or:n { \cs_if_exist_p:N #1 || }

\ExplSyntaxOff

\begin{document}

\section{Both}

\bothdefinedTF{\AAA}{\BBB}{yes}{no}\par
\def\AAA{}
\bothdefinedTF{\AAA}{\BBB}{yes}{no}\par
\def\BBB{}
\bothdefinedTF{\AAA}{\BBB}{yes}{no}\par

\section{All}

\alldefinedTF{\CCC\DDD\EEE}{yes}{no}\par
\def\CCC{}
\alldefinedTF{\CCC\DDD\EEE}{yes}{no}\par
\def\DDD{}
\alldefinedTF{\CCC\DDD\EEE}{yes}{no}\par
\def\EEE{}
\alldefinedTF{\CCC\DDD\EEE}{yes}{no}\par

\section{Either}

\eitherdefinedTF{\FFF}{\GGG}{yes}{no}\par
\def\GGG{}
\eitherdefinedTF{\FFF}{\GGG}{yes}{no}\par

\section{One}

\onedefinedTF{\HHH\III\JJJ}{yes}{no}\par
\def\III{}
\onedefinedTF{\HHH\III\JJJ}{yes}{no}\par

\end{document}

在此处输入图片描述

答案2

您可以进行\@firstoftwo/\@secondoftwo嵌套\if..检查:

\documentclass{article}

\begin{document}

\makeatletter

\newcommand\A{defined}%
\newcommand\B{defined}%


\ifdefined\A\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@firstoftwo}{%
   \ifdefined\B\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
   {\@firstoftwo}%
   {\@secondoftwo}%
}%
{At least one of the macros A,B is defined}{Neither A nor B is defined}%



\ifdefined\A\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
   \ifdefined\B\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
   {\@firstoftwo}%
   {\@secondoftwo}%
}{\@secondoftwo}%
{Both A and B is defined}{At least one of the macros A,B is undefined}%



\ifdefined\A\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
   \ifdefined\B\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
   {\expandafter\@firstoftwo\@firstoftwo}%
   {\expandafter\@secondoftwo\@firstoftwo}%
}{%
   \ifdefined\B\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
   {\expandafter\@firstoftwo\@secondoftwo}%
   {\expandafter\@secondoftwo\@secondoftwo}%
}%
{{A defined, B defined}{A defined, B undefined}}%
{{A undefined, B defined}{A undefined, B undefined}}%

\end{document}

或者你这样做:

\documentclass{article}

\newcommand\exchange[2]{#2#1}%
\newcommand\chooseoftwo[4]{%
   % #1 - which one of two argument to pick and to return nested in braces
   % #2 - tokens to prepend to the returned argument
   % #3 - argument 1
   % #4 - argument 2
   \expandafter\exchange\expandafter{#1{{#3}}{{#4}}}{#2}%
}%

\begin{document}

\makeatletter

%\newcommand\A{defined}%
\newcommand\B{defined}%

\ifdefined\A\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
   \ifdefined\B\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
   {\chooseoftwo{\@firstoftwo}{\chooseoftwo{\@firstoftwo}{\@firstoftwo}}}%
   {\chooseoftwo{\@secondoftwo}{\chooseoftwo{\@firstoftwo}{\@firstoftwo}}}%
}{%
   \ifdefined\B\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
   {\chooseoftwo{\@secondoftwo}{\chooseoftwo{\@secondoftwo}{\@firstoftwo}}}%
   {\chooseoftwo{\@secondoftwo}{\chooseoftwo{\@secondoftwo}{\@secondoftwo}}}%
}%
{A defined, B defined}%
{A defined, B undefined}%
{A undefined, B defined}%
{A undefined, B undefined}%

\end{document}

您可以实现一个宏

\nestcondition{⟨name of if-switch⟩}%
              {⟨arguments of if-switch⟩}

其计算结果\@firstoftwo取决于\@secondoftwo条件是否满足:

\documentclass{article}

\makeatletter
\newcommand\exchange[2]{#2#1}
\newcommand\nestcondition[2]{%
  \csname @%
  \csname
  \expandafter\exchange
  \expandafter{%
    \csname fi\endcsname
  }{%
    #1\endcsname#2\expandafter\@firstoftwo\else\expandafter\@secondoftwo
  }%
  {first}{second}oftwo\endcsname
}%
\newcommand\nestunlesscondition[2]{%
  \csname@%
  \expandafter\unless\csname
  \expandafter\exchange
  \expandafter{%
    \csname fi\endcsname
  }{%
    #1\endcsname#2\expandafter\@firstoftwo\else\expandafter\@secondoftwo
  }%
  {first}{second}oftwo\endcsname
}%
\makeatother

\begin{document}

\newcommand\A{defined}%
\newcommand\B{defined}%

\makeatletter

\nestcondition{ifdefined}{\A}{\@firstoftwo}{%
  \nestcondition{ifdefined}{\B}{\@firstoftwo}{\@secondoftwo}%
}
{At least one of the macros A,B is defined}{Neither A nor B is defined}%



\nestcondition{ifdefined}{\A}{%
  \nestcondition{ifdefined}{\B}{\@firstoftwo}{\@secondoftwo}%
}{%
  \@secondoftwo
}
{Both A and B is defined}{At least one of the macros A,B is undefined}%


\end{document}

相关内容