我正在寻找一种 LaTeX 方法来控制宏扩展,这取决于某些宏是否被定义。我正在寻找类似这样的东西(但实际上有效):
\newcommand[1]{\checkfor}{
\if\isdef\csname{#1}
... expand this if command exists ...
\else
... expand this if command does not exist ...
\fi
}
然后可以使用
\checkfor{CommandName}
(这个例子当然是没用的。我想要使用这种扩展的实际代码是一个包,它从一组更大的可能的宏中动态创建大量的宏,并且对“所有宏”都有默认行为。由于可能不存在“所有”宏,我需要某种方法来测试一个宏是否被声明,然后才能根据它的值进行扩展)。
答案1
这是你想要的:
\documentclass[12pt]{article}
\newcommand{\checkfor}[1]{%
\ifcsname#1\endcsname%
... command '#1' exists ...%
\else%
... command '#1' does not exist ...%
\fi%
}
\begin{document}
\checkfor{CommandName}\par
\checkfor{section}
\end{document}
答案2
etoolbox
为此提供了两个宏:
\ifdef{<control sequence>}{<true>}{<false>}
Expands to <true> if the <control sequence> is defined, and to <false> otherwise.
Note that control sequences will be considered as defined even if their meaning
is \relax. This command is a LaTeX wrapper for the e-TeX primitive \ifdefined.
\ifcsdef{<csname>}{<true>}{<false>}
Similar to \ifdef except that it takes a control sequence name as its first argument.
This command is a LaTeX wrapper for the e-TeX primitive \ifcsname.
答案3
此处的 LaTeX 内核标准宏\@ifundefined
为
\@ifundefined{foo}
{%
% \foo not defined
}
{%
% \foo defined
}%
在早期的 LaTeX2e 版本中,此测试不“可扩展”,并且会导致\foo
等于\relax
如果之前未定义,彼得的回答,这意味着这些问题不再存在。(由于 LaTeX2e 内核现在需要并使用 e-TeX,因此这种改变是可能的。)
答案4
测试的不可扩展变体,无需任何扩展:
\documentclass{article}
\makeatletter
\DeclareRobustCommand\checkfor[1]{%
\begingroup
\expandafter\ifx\csname#1\endcsname\relax\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
\expandafter\endgroup\expandafter\ifx\csname#1\endcsname\relax\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}{\endgroup\@firstoftwo}%
}%
\makeatother
\begin{document}
\verb|\LaTeX| is \checkfor{LaTeX}{defined}{undefined}.
\verb|\relax| is \checkfor{relax}{defined}{undefined}.
\verb|\UndefiNED| is \checkfor{UndefiNED}{defined}{undefined}.
\verb|\UndefiNED| is \checkfor{UndefiNED}{defined}{undefined}.
\verb|\UndefiNED| is \checkfor{UndefiNED}{defined}{undefined}.
\end{document}