缺少某些参数时具有多个参数的宏

缺少某些参数时具有多个参数的宏

我想定义一个带有两个参数的命令,\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

这是一个xparse使用g说明符作为可能的可选第二个(!!!)参数的解决方案,g说明符允许{}分隔可选参数,但在我看来,[]这是一种更清晰的方法。

\documentclass{article}

\usepackage{xparse}


\NewDocumentCommand{\xparsecmd}{mg}{%
  \IfValueTF{#2}{%
    optional #1 and #2
  }{%
    Only #1 and #1
  }%
}

\begin{document}

\xparsecmd{hello}

\xparsecmd{hello}{World}

\end{document}

在此处输入图片描述

答案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
    

相关内容