嵌套的 newcommand 和扩展的 \@nil

嵌套的 newcommand 和扩展的 \@nil

我正在创建一个命令来生成一系列具有相同样式的宏。例如1

\newcommand{\newcustommacro}[2]{\newcommand{#1}[1][Default]{#2{##1}}}
\newcustommacro{\macroA}{\textbf}

现在,我希望我的宏具有如果未传递可选参数,则会出现特殊行为因此我使用 David Carlisle 对该问题的回答。

然而,当该\newcommand方法嵌套在另一个方法中时\newcommand,它就会停止工作。

\documentclass{standalone}

\makeatletter
\newcommand{\testA}[1][\@nil]{
  \def\tmp{#1}%
  \ifx\tmp\@nnil%
    No arg: Hello%
  \else
    Yes arg: Bye(#1)%
  \fi
}
\makeatother

\newcommand{\makeamacro}[2]{%
  \makeatletter
  \newcommand{#1}[1][\@nil]{
    \def\tmp{##1}%
    \ifx\tmp\@nnil%
      No arg: Hello%
    \else
      Yes arg: #2(##1)
    \fi
  }
  \makeatother
}

\makeamacro{\testB}{Bye}

\begin{document}

  testA, no arg: \testA

  testA, yes arg: \testA[arg]

  testB, no arg: \testB

  testB, yes arg: \testB[arg]

\end{document}

输出

我按照将参数传递给嵌套新命令的要求将 # 加倍了。对于 @ 我需要做什么?我被难住了。

我不反对,xparse所以如果有人建议嵌套版本egreg 的回答对于上面链接的相同问题那么这也是可以的。


1:我知道这个例子只是制作一个宏,基本上就是\textbf{}

答案1

您放置的\makeatletter位置\makeatother不对。

如果你想使用@名称中包含的宏,\@nnil例如所有的代码应该被\makeatletter和包围\makeatother

\documentclass{article}

\makeatletter
\newcommand{\testA}[1][\@nil]{% <--- don't forget
  \def\tmp{#1}%
  \ifx\tmp\@nnil
    No arg: Hello%
  \else
    Yes arg: Bye(#1)%
  \fi
}

\newcommand{\makeamacro}[2]{%
  \newcommand{#1}[1][\@nil]{% <--- don't forget
    \def\tmp{##1}%
    \ifx\tmp\@nnil
      No arg: Hello%
    \else
      Yes arg: #2(##1)
    \fi
  }
}
\makeatother

\makeamacro{\testB}{Bye}

\begin{document}

  testA, no arg: \testA

  testA, yes arg: \testA[arg]

  testB, no arg: \testB

  testB, yes arg: \testB[arg]

\end{document}

在此处输入图片描述

话虽如此,但从xparse这个方面来说更容易:

\usepackage{xparse}

\NewDocumentCommand{\testA}{o}{%
  \IfNoValueTF{#1}
    {No arg: Hello}%
    {Yes arg: Bye(#1)}%
}

\NewDocumentCommand{\makeamacro}{mm}{%
  \NewDocumentCommand{#1}{o}{%
    \IfNoValueTF{##1}
      {No arg: Hello}%
      {Yes arg: #2(##1)}%
  }%
}

答案2

您是否搜索类似的东西?(xparser)

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\testA}{o D(){Bye}}{
  \IfNoValueTF {#1}
    {No arg: Hello}
    {Yes arg: #2(#1)}
}

\begin{document}

  testA, no arg: \testA 

  testA, yes arg: \testA[arg]

  testA, yes arg: \testA[arg](notbye)

\end{document}

相关内容