考虑以下 MWE:
\documentclass{standalone}
\newcommand{\myname}{ss}
\newcommand{\mycmd}{\ifx\myname\undefined{Please enter your name}\else{Professor \myname}\fi}
\begin{document}
\mycmd
\end{document}
我不知道为什么上面的命令返回Professor \myname
是否\newcommand{\myname}{}
为空?!
答案1
当然,您可以检查\myname
标记列表的内容以确定它是否包含名称。但是,这种方法需要一定程度的解析,因为您(大概)正在制作用户界面。例如,如果用户做了\newcommand\myname{}
或\newcommand\myname{ }
或根本\let\myname\relax
没有定义\myname
,则都需要不同的测试,这开始变得有点笨拙。
对于最简单的情况,即命令被定义/未定义,以及(如果已定义)为空/不为空,您可以编写两个嵌套条件;一个\ifx\myname\@undefined
,另一个\ifx\myname\@empty
1:
\makeatletter
\newcommand{\mycmd}{%
\ifx\myname\@undefined
Please enter your name%
\else
\ifx\myname\@empty
Please enter your name%
\else
Professor \myname
\fi
\fi}
\makeatother
\newcommand*{\myname}{ss}%
[1]通过这种方法,用户必须使用\newcommand*
,否则\ifx\myname\@empty
测试将失败,即使用户确实使用了\newcommand{\myname}{ss}
。为了允许两个都 \newcommand
你\newcommand*
需要其他嵌套条件\ifx\myname\long@empty
然后定义\long\def\long@empty{}
。它很快就会变得无法维护。
这是一个稍微好一点的用户界面(用户不必知道\newcommand
),它已经告诉代码是否给出了名称(不管名称实际上是什么)。
该命令\setname
(与 LaTeX 的 非常相似\author
)定义了包含名称的标记列表\myname
,并将条件设置\if@name@set
为\iftrue
。如果\setname
没有使用 ,则为\if@name@set
并且\iffalse
包含\myname
默认值。
\documentclass{article}
\makeatletter
\newcommand{\setname}[1]{%
\let\if@name@set\iftrue
\gdef\myname{#1}}
\let\if@name@set\iffalse
\gdef\myname{Please enter your name}
\newcommand{\mycmd}{%
\if@name@set
Professor \myname
\else
\textbf{??\myname??}%
\fi}
\makeatother
\begin{document}
\mycmd
\setname{X}% set the name
\mycmd % print again
\end{document}
答案2
Phelype 的回答解释了许多问题。
但还有另一种方法:
\documentclass{standalone}
\newcommand{\mycmd}{%
\ifdefined\myname
Professor \myname
\else
Please enter your name%
\fi
}
\newcommand{\myname}{ss}
\begin{document}
\mycmd
\end{document}
对于这种编程,通常最好使用“私有”命令,以便涵盖用户可能\myname
为自己的目的而定义的可能操作。
当然,主要代码应该放在.sty
或文件中。.cls
\documentclass{standalone}
\makeatletter % <- this should not appear in a .sty or .cls file
%% code for .sty or .cls
\newcommand{\printadvisor}{%
\ifdefined\cfg@advisor
Professor \cfg@advisor
\else
\PackageWarning{cfgpackage}{Missing advisor's name}% or \ClassWarning
Please enter advisor's name%
\fi
}
\newcommand{\setadvisor}[1]{\gdef\cfg@advisor{#1}}
%% end of code for .sty or .cls
\makeatother % <- this should not appear in a .sty or .cls file
\begin{document}
%% in the document “metadata part”
\setadvisor{A. Einstein}
\printadvisor
\end{document}
答案3
我可以提供一个\romannumeral0
基于 -expansion 的例程\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined
来检查宏参数是否由未定义或定义为空白的单个标记组成。(“定义为空白”意味着扩展标记要么根本不产生标记,要么只产生空格标记。)
该例程不需要 ε-TeX 扩展或类似的东西,也可以在扩展上下文中应用,例如在 内\csname..\endcsname
。结果将在两个扩展步骤/两次“命中”后提供\expandafter
。
该例程不使用任何\if..\else..\fi
。
该例程不会因其参数中的 (unbalanced) \if..
/ \else
/\fi
或 unbalanced \csname
/而感到困惑。\endcsname
例行公事将不扩大参数,它只会“查看”由第一个参数形成的标记集,以“决定”是否要传递形成第二个参数的标记或形成第三个参数的标记。
可能的陷阱:如果参数是单个宏标记,且不处理参数,则检查该宏标记是否定义为空白,方法是通过 LaTeX 2ε-kernel-macro剥离前缀 (-thingie) 后“查看”\meaning
宏标记的。“查看”宏标记的含义而不是“查看”宏标记的顶层扩展是为了确保在宏标记扩展为 的情况下测试不会失败。(您可以执行以下操作:\UD@CheckWhetherBlank
macro:->
\strip@prefix
\outer
\def\unfold{\umbrella}
\outer\def\umbrella{No raindrops on my head, please!}
,\unfold
并将扩展为 ,\umbrella
即\outer
。在这种情况下,直接将顶层扩展的结果\unfold
作为参数传递给宏来检查该扩展的空白性是不可能的,因为这意味着将 -token\outer
作为宏参数的组成部分。)
但在这种情况下查看含义并不完全安全:如果整数参数的\escapechar
值为 32(32 是 ASCII 和 Unicode 中空格字符的代码点数,这是当今 TeX 引擎的可能内部字符编码方案),或者其值超出了 TeX 引擎内部字符编码方案的可能代码点数范围,则检查“含义的空白性”不会产生令牌被定义为也提供名称仅由空格组成的控制序列的情况,例如控制空间\
,或通过 构造的东西\csname..\endcsname
,例如:
\def\insertfivechars#1#2{#1#2#2#2#2#2}
\insertfivechars{\expandafter\def\csname}{ }\endcsname{The name of this control sequence consists of five spaces.}
\insertfivechars{\expandafter\show\csname}{ }\endcsname
% But:
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\scratch
\expandafter\expandafter\expandafter{%
\insertfivechars{\csname}{ }\endcsname
}
\escapechar=-1
\message{X\meaning\scratch X}
\bye
为了好玩,检查标记是否未定义是通过检查应用结果是否\meaning
提供以标记开头的标记序列来完成的。u12n12d12e12f12i12n12e12d12
可能检查含义是否以或开头就足够了。 [如果有人能验证这一点并添加评论,我会很高兴也很感激。;-)]u12
u12n12
附录:
我不知道问这个问题时我在想什么。
例如,有一个-primitive,这意味着当具有正值时\uppercase
,检查是不够的。u12
\escapechar
菲利佩·奥莱尼克指出\escapechar
需要考虑的值,并且存在\underline
-原语,因此至少需要检查。u12n12d12e12f12
\UD@CheckWhetherNull
我对这个问题的回答详细解释了空测试“空标记列表的可扩展测试——方法、性能和稳健性”. 在那个答案中它的名字不是\UD@CheckWhetherNull
而是\CheckWhetherEmpty
。
\documentclass[a4paper]{article}
%===================[adjust margins/layout for the example]====================
\csname @ifundefined\endcsname{pagewidth}{}{\pagewidth=\paperwidth}%
\csname @ifundefined\endcsname{pdfpagewidth}{}{\pdfpagewidth=\paperwidth}%
\csname @ifundefined\endcsname{pageheight}{}{\pageheight=\paperheight}%
\csname @ifundefined\endcsname{pdfpageheight}{}{\pdfpageheight=\paperheight}%
\textwidth=\paperwidth
\oddsidemargin=1.25cm
\marginparsep=.125\oddsidemargin
\marginparwidth=\oddsidemargin
\advance\marginparwidth-2\marginparsep
\advance\textwidth-2\oddsidemargin
\advance\oddsidemargin-1in
\evensidemargin=\oddsidemargin
\textheight=\paperheight
\topmargin=1.25cm
\footskip=.5\topmargin
{\normalfont\global\advance\footskip.5\ht\strutbox}%
\advance\textheight-2\topmargin
\advance\topmargin-1in
\headheight=0ex
\headsep=0ex
\pagestyle{empty}
\parindent=0ex
\parskip=0ex
\topsep=0ex
\partopsep=0ex
%==================[eof margin-adjustments]====================================
\makeatletter
%=====[code for \UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined]=======
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral0\expandafter\@secondoftwo\string{\expandafter
\@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
\@secondoftwo\string}\@firstoftwo\expandafter{} \@secondoftwo}%
{\@firstoftwo\expandafter{} \@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument is blank (empty or only spaces):
%%.............................................................................
%% -- Take advantage of the fact that TeX discards space tokens when
%% "fetching" _un_delimited arguments: --
%% \UD@CheckWhetherBlank{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that
%% argument which is to be checked is blank>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not blank>}%
\newcommand\UD@CheckWhetherBlank[1]{%
\romannumeral\expandafter\expandafter\expandafter\@secondoftwo
\expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo#1{}.}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument's first token is a catcode-1-character
%%.............................................................................
%% \UD@CheckWhetherBrace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has leading
%% catcode-1-token>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has no leading
%% catcode-1-token>}%
\newcommand\UD@CheckWhetherBrace[1]{%
\romannumeral0\expandafter\@secondoftwo\expandafter{\expandafter{%
\string#1.}\expandafter\@firstoftwo\expandafter{\expandafter
\@secondoftwo\string}\expandafter\expandafter\@firstoftwo{ }{}%
\@firstoftwo}{\expandafter\expandafter\@firstoftwo{ }{}\@secondoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Exchange two arguments. (From each argument an outermost level of
%% surrounding braces will be removed if present.)
%%-----------------------------------------------------------------------------
\newcommand\UD@Exchange[2]{#2#1}%
%%-----------------------------------------------------------------------------
%% Check whether argument's leading tokens form a specific
%% token-sequence that does not contain explicit character tokens of
%% category code 1 or 2:
%%.............................................................................
%% \UD@CheckWhetherLeadingTokens{<argument which is to be checked>}%
%% {<a <token sequence> without explicit
%% character tokens of category code
%% 1 or 2>}%
%% {a <single non-space token> that does
%% _not_ occur in <token sequence> >}%
%% {<internal token-check-macro>}%
%% {<tokens to be delivered in case
%% <argument which is to be checked> has
%% <token sequence> as leading tokens>}%
%% {<tokens to be delivered in case
%% <argument which is to be checked>
%% does not have <token sequence> as
%% leading tokens>}%
\newcommand\UD@CheckWhetherLeadingTokens[4]{%
\romannumeral0\UD@CheckWhetherNull{#1}%
{\UD@Exchange{ }\expandafter\@secondoftwo}%
{\expandafter\@secondoftwo\string{\expandafter
\UD@@CheckWhetherLeadingTokens#4#3#1#2}{}}%
}%
\newcommand\UD@@CheckWhetherLeadingTokens[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo{}#1}%
{\UD@Exchange{\@firstoftwo}}{\UD@Exchange{\@secondoftwo}}%
{\UD@Exchange{ }{\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter}\expandafter\expandafter
\expandafter}\expandafter\@secondoftwo\expandafter{\string}%
}%
%%-----------------------------------------------------------------------------
%% \UD@internaltokencheckdefiner{<internal token-check-macro>}%
%% {<token sequence>}%
%% Defines <internal token-check-macro> to snap everything
%% until reaching <token sequence>-sequence and spit that out
%% nested in braces.
%%-----------------------------------------------------------------------------
\newcommand\UD@internaltokencheckdefiner[2]{%
\@ifdefinable#1{\long\def#1##1#2{{##1}}}%
}%
\begingroup
%%-----------------------------------------------------------------------------
%% Check whether argument is a macro that takes arguments
%%.............................................................................
%% Temporary/interim-definition/Usage as scratch-macro:
\newcommand\UD@CheckWhetherArgumentlessMacroMeaning[5]{%
% #1 = phrase "undefined" in catcode-12-character-tokens
% #2 = phrase "macro:->" in catcode-12-character-tokens
% #3 = phrase "\long macro:->" in catcode-12-character-tokens
% #4 = phrase "\protected\long macro:->" in catcode-12-character-tokens
% #5 = phrase "\protected macro:->" in catcode-12-character-tokens
\endgroup
\UD@internaltokencheckdefiner{\UD@ExtractUndefined}{#1}%
\UD@internaltokencheckdefiner{\UD@ExtractMacro}{#2}%
\UD@internaltokencheckdefiner{\UD@ExtractLongMacro}{#3}%
\UD@internaltokencheckdefiner{\UD@ExtractProtectedLongMacro}{#4}%
\UD@internaltokencheckdefiner{\UD@ExtractProtectedMacro}{#5}%
\UD@internaltokencheckdefiner{\UD@ExtractSpace}{ }%
%%-----------------------------------------------------------------------------
%% Check whether argument is a macro that takes arguments
%%.............................................................................
%% \expandafter\UD@CheckWhetherArgumentlessMacroMeaning
%% \expandafter{\meaning <token>}{%
%% <Tokens to be delivered in case <token> is a macro that does not take
%% arguments>
%% }{%
%% <Tokens to be delivered in case <token> is not a macro that does not
%% take arguments>
%% }%
\newcommand\UD@CheckWhetherArgumentlessMacroMeaning[1]{%
\UD@CheckWhetherLeadingTokens{##1}{#2}{.}{\UD@ExtractMacro}{\@firstoftwo}{%
\UD@CheckWhetherLeadingTokens{##1}{#3}{.}{\UD@ExtractLongMacro}{\@firstoftwo}{%
\UD@CheckWhetherLeadingTokens{##1}{#4}{.}{\UD@ExtractProtectedLongMacro}{\@firstoftwo}{%
\UD@CheckWhetherLeadingTokens{##1}{#5}{.}{\UD@ExtractProtectedMacro}{\@firstoftwo}{%
\@secondoftwo
}%
}%
}%
}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument is a token that is undefined and can be defined.
%%.............................................................................
%% \expandafter\UD@CheckWhetherUndefinedMeaning
%% \expandafter{\meaning <token>}{%
%% <Tokens to be delivered in case <token> is undefined and can be defined.>
%% }{%
%% <Tokens to be delivered in case <token> is not undefined/cannot be
%% defined.>
%% }%
\newcommand\UD@CheckWhetherUndefinedMeaning[1]{%
\UD@CheckWhetherLeadingTokens{##1}{#1}{.}{\UD@ExtractUndefined}%
}%
}%
\def\@tempa{\protected macro:->}\@onelevel@sanitize\@tempa
\expandafter\UD@Exchange\expandafter{\expandafter{\@tempa}}{%
\edef\@tempa{\string\protected\long macro:->}\@onelevel@sanitize\@tempa
\expandafter\UD@Exchange\expandafter{\expandafter{\@tempa}}{%
\def\@tempa{\long macro:->}\@onelevel@sanitize\@tempa
\expandafter\UD@Exchange\expandafter{\expandafter{\@tempa}}{%
\def\@tempa{macro:->}\@onelevel@sanitize\@tempa
\expandafter\UD@Exchange\expandafter{\expandafter{\@tempa}}{%
\def\@tempa{undefined}\@onelevel@sanitize\@tempa
\expandafter\UD@Exchange\expandafter{\expandafter{\@tempa}}{%
\UD@CheckWhetherArgumentlessMacroMeaning
}%
}%
}%
}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument is undefined or defined blank (=yields no tokens or
%% only space-tokens)/a single token:
%%.............................................................................
%% \UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{%
%% <Argument which is to be checked>%
%% }{%
%% <Tokens to be delivered in case <argument which is to be checked> is a
%% single token that is undefined or defined blank>%
%% }{%
%% <Tokens to be delivered in case <argument which is to be checked> is not a
%% single token that is undefined or defined blank>%
%% }%
\newcommand\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined[1]{%
\romannumeral0%
\UD@CheckWhetherBlank{#1}{%
% Argument is blank:
\@firstoftwo\expandafter{} \@secondoftwo
}{%
\UD@CheckWhetherBrace{#1}{%
% The leading opening brace implies that further examination
% is not needed:
\@firstoftwo\expandafter{} \@secondoftwo
}{%
% Argument's first token is not an opening brace and
% therefore its first token can safely be "hit" by \meaning:
\UD@CheckWhetherLeadingTokens{#1}{ }{.}{\UD@ExtractSpace}%
{%
% Argument has a leading space. Thus argument's first token
% cannot be removed by "gobbling" a non-delimited argument.
% The leading space implies that further examination
% is not needed:
\@firstoftwo\expandafter{} \@secondoftwo
}{%
% Argument's first token is a non-space-token that can safely be
% gobbled and argument's first token can safely be "hit" by
% \meaning:
\expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo{}#1}{%
% Argument consists of a single token which can safely be "hit"
% by \meaning:
\expandafter\UD@CheckWhetherUndefinedMeaning\expandafter{\meaning#1}%
{%
%The meaning denotes that the single token is undefined:
\@firstoftwo\expandafter{} \@firstoftwo
}%
{%
%The meaning denotes that the single token is not undefined:
\expandafter\UD@CheckWhetherArgumentlessMacroMeaning\expandafter{\meaning#1}%
{%
%The meaning denotes that the single token is an argumentless macro:
\expandafter\expandafter
\expandafter \UD@CheckWhetherBlank
\expandafter\expandafter
\expandafter {%
\expandafter\strip@prefix
\meaning#1}{%
%The meaning denotes that the single token is defined blank:
%In the edge case of `\escapechar` having a negative value or
%having the value 32 (32 is the code-point of the space character
%both in ASCII and in Unicode, the possible internal coding-schemes
%of TeX-engines), the definition of the token might also
%contain control sequences whose name consists of spaces
%only, e.g., control spaces \ .
\@firstoftwo\expandafter{} \@firstoftwo
}{%
%The meaning denotes that the single token is defined, but not blank:
\@firstoftwo\expandafter{} \@secondoftwo
}%
}%
{%
%The meaning denotes that the single token is not an argumentless macro:
\@firstoftwo\expandafter{} \@secondoftwo
}%
}%
}{%
% Argument consists of several tokens and the argument's
% first token neither is a space nor is a brace:
% The circumstance of there being severak tokens implies that
% further examination is not needed:
\@firstoftwo\expandafter{} \@secondoftwo
}%
}%
}%
}%
}%
%%===[eof code for \UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined]====
\makeatother
\begin{document}
\makeatletter
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\UndEFiNeD}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\UndEFiNeD}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\UndEFiNeD\UndEFiNeD}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\UndEFiNeD\UndEFiNeD}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{ }{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{ }{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\LaTeX}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\LaTeX}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\@firstoftwo}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\@firstoftwo}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\empty}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\empty}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\protected\long\def\myblank{ }%
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\myblank}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\myblank}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\myblank\myblank}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\myblank\myblank}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{{\myblank}}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{{\myblank}}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\else}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{\else}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{#}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{#}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{X}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{X}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\noindent\null\hrulefill
\begin{verbatim}
\catcode`\X=13
\protected\defX{}%
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{X}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{verbatim}
yields:
\catcode`\X=13
\protected\defX{}%
\UD@CheckWhetherArgIsSingleTokenDefinedBlankOrUndefined{X}{%
Arg is a single token which is definable and either currently undefined or defined blank.
}{%
Arg is a not a single token which is definable and either currently undefined or defined blank.
}%
\end{document}
答案4
使用ifmtarg
包(加上一些代码简化):
% undefprob.tex SE 527084
\documentclass{standalone}
\usepackage{ifmtarg}
\makeatletter
\newcommand{\myname}[1]{\@ifmtarg{#1}{Please enter your name}%
{Professor #1}}
\makeatother
%\newcommand{\mycmd}{\ifx\myname\undefined{Please enter your name}\else{Professor \myname}\fi}
\begin{document}
Empty arg: \myname{}
Non-empty arg: \myname{Jones}
\end{document}
上述代码检查 的参数是否为\myname
空(空白)。如果为空,则要求输入姓名,否则打印 Professor 和 的参数\myname
。