我想将两个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}