如果我想创建一个名为的新命令\AddTwoArguments
,它需要二参数,我可以这样做:
\newcommand{\AddTwoArguments}[2]{ {\bfseries#1} {`#2'} }
所以,
\AddTwoArguments{A}{B}
将输出:
A‘B’
太棒了。世界再幸福不过了。
但是,假设我想创建一个名为的新命令,\AddAnyEvenNumberOfArguments
它适用于任何偶数对于每一对参数,它总是遵循上述模式。
例如,
\AddAnyEvenNumberOfArguments{A}{B}
仍会给出:
A‘B’
然而
\AddAnyEvenNumberOfArguments{A}{B}{C}{D}{E}{F}
将会得到:
A‘B’C‘D’埃'F'
请问该怎么做?
例如,
答案1
你可以使用停止标准来停止对成对参数的搜索。这样的停止标准可以是\ByTwo ... \StopByTwo
:
\documentclass{article}
\makeatletter
\newcommand{\ByTwo}{\@ifnextchar\StopByTwo\relax\@ByTwo}
\newcommand{\@ByTwo}[2]{ {\bfseries #1} {`#2'} \ByTwo}
\makeatother
\let\StopByTwo\relax
\begin{document}
\ByTwo{A}{B}\StopByTwo
\ByTwo{A}{B}{C}{D}{E}{F}\StopByTwo
\ByTwo ABCDEF\StopByTwo
\end{document}
答案2
以下是如何使用停止器实现这样的宏。答案在 ConTeXt 中,因为我使用\dodoublegroupempty
来自 ConTeXt 的宏。我相信 LaTeX 内核中会有类似的辅助宏,可用于 LaTeX 解决方案。
\unexpanded\def\ByTwo
{\dodoublegroupempty\doByTwo}
\def\doByTwo#1#2%
{\ifsecondargument
{\bf #1} ‘#2’
\expandafter\ByTwo
\fi}
\starttext
\startlines
\ByTwo{A}{B}
\ByTwo{A}{B}{C}{D}
\ByTwo{A}{B}{C}{D}{E}{F}
\stoplines
\stoptext
这使
答案3
我建议一个没有结束标记的答案。
这个问题有些问题:如果你提供的参数数量是奇数,那么答案是什么?我的答案是:
\AddAnyEvenNumberOfArguments{A}{B}{C}{D}{E}
应该显示
但如果您想要其他行为,您可以轻松更改代码。
\documentclass{article}
\makeatletter
\newcommand\AddAnyEvenNumberOfArgument{%
\@ifnextchar\bgroup{\AddCoupleArgument}{}
}
\newcommand\AddCoupleArgument[1]{%
\textbf{#1}
\@ifnextchar\bgroup{\AddSecondArgument}{\AddEmptySecondArgument}
}
\newcommand\AddSecondArgument[1]{%
`#1'
\@ifnextchar\bgroup{\AddCoupleArgument}{}
}
\newcommand\AddEmptySecondArgument{%
`'
}
\makeatother
\begin{document}
\AddAnyEvenNumberOfArgument{A}\par
\AddAnyEvenNumberOfArgument{A}{B}\par
\AddAnyEvenNumberOfArgument{A}{B}{C}\par
\AddAnyEvenNumberOfArgument{A}{B}{C}{D}\par
\AddAnyEvenNumberOfArgument{A}{B}{C}{D}{E}\par
\AddAnyEvenNumberOfArgument{A}{B}{C}{D}{E}{F}\par
\AddAnyEvenNumberOfArgument{A}{B}{C}{D}{E}{F}{G}
\end{document}
注意如果 \AddAnyEvenNumberOfArguments 后面的代码以左括号开头,那么这个组将被这个宏吞噬!合乎逻辑。正常。添加 \relax 例如
\AddAnyEvenNumberOfArgument{A}{B}{C}{D}{E}{F}\relax
{\bfseries That's all folks}