我怎样才能以安全的方式进行测试(即不保留令牌,如上所述这里) 如果扩展宏参数为空?
答案1
你可以使用一个\romannumeral
技巧:
\if\relax\detokenize\expandafter{\romannumeral-`\Q#1}\relax
后面缺失的空格`\Q
将触发扩展#1
(当然是在宏替换之后)。由于此扩展在第一个不可扩展的标记处结束,因此这应该是您想要的。
但是前导空格将被忽略。
\def\notempty{\relax}
\def\perhapsempty{\empty}
\if\relax\detokenize\expandafter{\romannumeral-`\Q\empty}\relax
\message{EMPTY}
\else
\message{NOT EMPTY}
\fi
\if\relax\detokenize\expandafter{\romannumeral-`\Q\notempty}\relax
\message{EMPTY}
\else
\message{NOT EMPTY}
\fi
\if\relax\detokenize\expandafter{\romannumeral-`\Q\perhapsempty}\relax
\message{EMPTY}
\else
\message{NOT EMPTY}
\fi
\if\relax\detokenize\expandafter{\romannumeral-`\Q\space}\relax
\message{EMPTY}
\else
\message{NOT EMPTY}
\fi
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014) (preloaded format=pdftex)
restricted \write18 enabled.
entering extended mode
(./tsanempty.tex EMPTY NOT EMPTY EMPTY EMPTY)
如果您不需要可扩展性并且相信您传递的令牌是完全可扩展的,则可以使用\edef
:
\begingroup\edef\x{#1}\expandafter\endgroup\expandafter
\if\expandafter\relax\detokenize\expandafter{\x}\relax
例如,
\begingroup\edef\x{\empty}\expandafter\endgroup\expandafter
\if\expandafter\relax\detokenize\expandafter{\x}\relax
\message{EMPTY}
\else
\message{NOT EMPTY}
\fi
\begingroup\edef\x{\notempty}\expandafter\endgroup\expandafter
\if\expandafter\relax\detokenize\expandafter{\x}\relax
\message{EMPTY}
\else
\message{NOT EMPTY}
\fi
\begingroup\edef\x{\perhapsempty}\expandafter\endgroup\expandafter
\if\expandafter\relax\detokenize\expandafter{\x}\relax
\message{EMPTY}
\else
\message{NOT EMPTY}
\fi
\begingroup\edef\x{\space}\expandafter\endgroup\expandafter
\if\expandafter\relax\detokenize\expandafter{\x}\relax
\message{EMPTY}
\else
\message{NOT EMPTY}
\fi
将返回
EMPTY NOT EMPTY EMPTY NOT EMPTY
其实,an\expandafter
是多余的,但是清晰度更好。
答案2
\documentclass{article}
\usepackage[T1]{fontenc}
\def\foo#1{\par \texttt{<\detokenize{#1}>}
\expandafter\if\relax\detokenize\expandafter{\romannumeral0#1}\relax
\if X#1X%
empty\else
not empty\fi
\else
not empty\fi}
\begin{document}
\foo{}
\foo{ }
\foo{\empty}
\foo{{}}
\foo{\sqrt}
\foo{\csname @gobble\endcsname{hello}}
\end{document}
答案3
你试过 ifmtarg 包吗?它提供了宏
\@ifmtarg{<arg>}{<Code for arg empty>}
{<Code for arg not empty>}
使用 texdoc ifmtarg 进行文档编写。