我想定义一个带有两个参数的命令,\mycommand{arg1}{arg2}
假设第二个参数不存在,那么它将用第一个参数代替第二个参数,换句话说,\mycommand{arg1}
相当于\mycommand{arg1}{arg1}
。
答案1
此语法依赖事实上,人们会使用括号来括起参数(否则问题就变得模棱两可,因为任何后续 token 可以解释作为第二个论点)。
\documentclass{article}
\makeatletter
\def\mycommand#1{\@ifnextchar\bgroup{\mycommandhelp{#1}}{\mycommandhelp{#1}{#1}}}
\makeatother
\def\mycommandhelp#1#2{Mycommands arguments: #1 and #2}
\begin{document}
\mycommand{arg1}
\mycommand{arg1}{arg2}
\end{document}
我只想补充一点,当只提供一个参数时,该参数后面的任何空格都会被吞噬。如果一个人总是想提供一个空格,无论使用 1 个还是 2 个参数,都可以定义
\def\mycommandhelp#1#2{Mycommands arguments: #1 and #2\ \ignorespaces}
如果有人不想自动提供空间,那么
\def\mycommandhelp#1#2{Mycommands arguments: #1 and #2\ignorespaces}
可用于。
正如 egreg 在他的回答中提到的,LaTeX 提供了可选参数。对于你的情况,一个简单的实现是:
\newcommand\mycommand[2][\relax]{\ifx\relax#1 The arguments are #2 and #2\else
The arguments are #1 and #2\fi}
使用调用语法作为\mycommand{arg1}
or else \mycommand[arg1]{arg2}
。
答案2
答案3
通常这是以以下形式实现的
\foo{Unique}
和
\foo[One]{Two}
这比括号中的可选参数更清晰。
经典的 LaTeX 方法是
\newcommand{\foo}{\@dblarg\name@foo}
\def\name@foo[#1]#2{Whatever we want to do with #1 and #2}
因此调用\foo{X}
将导致
无论我们想用 X 和 X 做什么
而调用\foo[X]{Y}
将导致
无论我们想用 X 和 Y 做什么
你xparse
可能会做
\usepackage{xparse}
\NewDocumentCommand{\foo}{om}{%
\IfNoValueTF{#1}{\realfoo{#2}{#2}}{\realfoo{#1}{#2}}%
}
\NewDocumentCommand{\realfoo}{mm}{%
Whatever we want to do with #1 and #2%
}
答案4
以防万一,这里有一个简单的解决方案
带有可选的第二个括号参数:
\def\foo#1{\edef\tmp{#1}\futurelet\next\fooaux} \def\fooaux{% \ifx\next\bgroup \expandafter\fooprocess \else \fooprocess\tmp \fi } \def\fooprocess#1{Something with \tmp\ and #1} \foo{bar} \foo{bar}{baz} \bye
带有可选括号第一个参数:
\def\foo{\futurelet\next\fooaux} \def\fooaux{% \ifx\next[ \expandafter\fooi \else \expandafter\fooii \fi } \def\fooii#1{\fooi[#1]{#1}} \def\fooi[#1]#2{Something with #1 and #2} \foo{bar} \foo[bar]{baz} \bye