我正在创建一个命令来生成一系列具有相同样式的宏。例如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}