\BODY 扩展问题

\BODY 扩展问题

在以下 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就“几乎完全展开了”。不能使用\edefas 会更自然,因为如果像它一样的东西\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}

相关内容