在以下 MWE 中,命令\testStringNotEmpty
测试参数是否为空。此测试非常可靠,因为参数可以包含命令或环境...monenv
如果主体(我在 \BODY 中捕获)为空,则环境将显示“空”,否则将显示“不空”。我的问题是,如果的主体monenv
是扩展为“空”的命令\macom
,那么它的行为与我预期的不同。这可能是因为\BODY
在调用之前应该完全展开\testStringNotEmpty
,而我尝试使用 \expandafter 似乎不起作用...
\documentclass{article}
\usepackage{environ}
\makeatletter
\newcommand{\testStringNotEmpty}[1]{%
\ifnum\pdfstrcmp{\unexpanded{#1}}{}=\z@
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi
}
\makeatother
\NewEnviron{monenv}%
{%
\expandafter\testStringNotEmpty\expandafter{\BODY}%
{Environment = NOT empty}%
{Environment = Empty}%
}
\newcommand{\macom}{}
\begin{document}
\begin{monenv}
\end{monenv}
\begin{monenv}
\macom
\end{monenv}
\begin{monenv}
\macom
\macom
\end{monenv}
\end{document}
编辑:使用egreg的解决方案\BODY
在环境中进行扩展monenv
,如果内容monenv
更复杂(现在反映到我的实际代码中),我现在会遇到一些问题。
因此,我monenv
根据 egreg 的解决方案重新定义。我定义了以下命令:
\newcommand{\hint}[1]{%
\testStringNotEmpty{#1}{hint : #1}{}}
我测试了一下:
\begin{monenv}
\hint{}
\end{monenv}
\begin{monenv}
\hint{}
\hint{}
\end{monenv}
这给了我第一个“空”(正如预期的那样)和第二个“不空”,我不想要......
答案1
\makeatletter
\NewEnviron{monenv}
{\begingroup\protected@edef\x{\endgroup
\noexpand\testStringNotEmpty{\BODY}}%
\x{Environment = NOT empty}{Environment = Empty}%
}
\makeatother
这样\BODY
就“几乎完全展开了”。不能使用\edef
as 会更自然,因为如果像它一样的东西\textbf
恰好出现在环境体内,\edef\x
就会惨败。
\x
展开后你将获得
\endgroup\testStringNotEmpty{<expansion of \BODY>}{true}{false}
并且\endgroup
将与前一个相对应\begingroup
(并删除 的定义\x
)。
答案2
由于您的定义,主体不会扩展\unexpanded
,如果您删除它,则在所有这些情况下都会得到空,但是主体中的某些东西可能会扩展,而您可能不希望扩展。这完全取决于……
答案3
\documentclass{article}
\usepackage{environ}
\newsavebox\BBox
\NewEnviron{monenv}%
{\savebox\BBox{\BODY}
\ifdim\wd\BBox=0pt\relax
Environment = empty \else Environment = Not Empty: =\BODY= \fi}
\newcommand\macom{}
\begin{document}
\begin{monenv}
\end{monenv}
\begin{monenv}
\macom
\end{monenv}
\begin{monenv}
\macom
\macom
\end{monenv}
\end{document}