如何使用 etoolbox 包来检查宏的参数是否已定义?

如何使用 etoolbox 包来检查宏的参数是否已定义?

我看见这个答案,它使用该etoolbox包创建一个带有可选参数的宏。不幸的是,我无法让它工作。这是一个最小的工作示例:

\documentclass[12pt]{article}
\usepackage{etoolbox}

\newcommand\mymacrotwo[2][]{
  \ifstrempty{#2}{
    #1: none
  }{
    #1: #2
  }
}

\begin{document}
\mymacrotwo{hello}

\mymacrotwo{hello}{world}
\end{document}

输出:

: hello
: hello world

不仅冒号位置不对,而且none如果第二个参数未定义,它也不会显示。问题出在哪里?

我也尝试过这个变体:

\documentclass[12pt]{article}
\usepackage{etoolbox}

\newcommand{\mymacro}[2]{#1 \ifboolexpr{ test {\ifdef{#2}} } {#2} {none}}

\begin{document}
\mymacro{hello}

\mymacro{hello}{world}
\end{document}

但输出如下:

hello
hello orldworld

这显然也是不对的。

答案1

如果 TeX 宏定义为具有两个参数,TeX 将总是为两个参数分配一些标记,或者引发错误。

定义

\newcommand\mymacrotwo[2]{
  \ifstrempty{#2}{
    #1: none
  }{
    #1: #2
  }
}

已经有一些缺点了,因为你添加了几个空格,这些空格会在打印输出中显示出来。更好的做法是

\newcommand\mymacrotwo[2]{%
  \ifstrempty{#2}%
   {%
    #1: none%
   }%
   {%
    #1: #2%
   }%
}

如何对齐替代括号是个人喜好问题,但行尾应该被遮盖,除非你想要一个可以展现的空间。

让我们看看如果你输入

\mymacrotwo{hello} and some text

宏有参数;第一个被确定为hello,因为扫描了一个括号;第二个参数将是a:在寻找参数时,TeX 会采用第一个非空间找到的标记,除非它是{;在这种情况下,参数是匹配的任何内容}

如果你打电话

\mymacrotwo{hello}
and some text

它会完全相同,因为 TeX 将行尾转换为空格,并且在寻找参数时会忽略空格。

技术说明:这里我谈论的是未限定参数,即在涉及定义的宏时所寻找的类型\newcommand

留一个空行也无济于事:

\mymacrotwo{hello}

and some text

第二个参数是\par,因为 TeX 将空行转换为\par标记。

让我们验证一下。我将使用宏的简化版本,仅打印其参数:

\documentclass{article}
\newcommand{\mymacrotwo}[2]{%
  ``{\ttfamily \#1 is \detokenize{#1}, \#2 is \detokenize{#2}}''%
}

\begin{document}
\mymacrotwo{hello} and some text

\mymacrotwo{hello}
and some text

\mymacrotwo{hello}

and some text
\end{document}

在此处输入图片描述

因此,如果你想按预期使用宏,你必须也可以叫它

\mymacrotwo{hello}{}

或者

\mymacrotwo{hello}{world}

实际上,xparse您可以定义具有所需特性的宏,但这是否符合 LaTeX 语法还有待商榷。

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\mymacrotwo}{ m g }
 {%
  \IfNoValueTF{#2}%
   {%
    #1: none%
   }
   {
    #1: #2%
   }%
 }

\begin{document}

\mymacrotwo{hello} and some text

\mymacrotwo{hello}{world} and some text

\end{document}

在此处输入图片描述

我绝对不会建议使用此功能。

相关内容