我如何检查我的命令是否收到 2 个或 3 个参数?

我如何检查我的命令是否收到 2 个或 3 个参数?

我知道如何使用\newifand在 LaTeX 中创建 if\else 结构\else。我想知道是否有办法检查命令给出的实际参数。例如,如果我有一个命令\newcommand{\mycomm}[3],并且在调用时我给它 2(两个)而不是 3(三个)个参数,我希望它的行为有所不同。

到目前为止,我在 SO 上找到的解决方案与确定空虚或处理可选参数有关;这不是我想要做的。

// 编辑:我需要的是类似以下内容:

\newcommand{\homeworkdata}[6]{
    \begin{flushleft}
        \noindent\makebox[\textwidth]{\LARGE \bf #1, #2 }
        \Repeat{2}{\ \\}
        \noindent\makebox[\textwidth]{\Large\bf  Homework \##3 }
    
        \ \\
    %  What I  need here is the option for the student to give me their first 
    and last name. If they do, I want their data to appear after "first & last name".
        \noindent\makebox[\textwidth]{\large \bf  \textbf{First} \& \textbf{Last} Name:  \enspace \myline{4in}}
         \Repeat{2}{\ \\ }
            \noindent\makebox[\textwidth]{\large \bf  UID (9 digits): \enspace \myline{3in}}
        \ \\ 
    \end{flushleft} 
            \Repeat{2}{\ \\}
}

答案1

2 种可能性

A

此处第三个参数是可选的。当然,它需要使用方括号而不是花括号语法。

\documentclass{article}
\newcommand\z[2]{\def\zone{#1}\def\ztwo{#2}\zaux}
\newcommand\zaux[1][]{%
  \ifx\relax#1\relax%
    Two arguments: \zone{} and \ztwo%
  \else%
    Three arguments: \zone, \ztwo, and #1%
  \fi
}
\begin{document}
\z{A}{B}

\z{A}{B}[C]
\end{document}

在此处输入图片描述

这允许在第二个参数中使用逗号分隔的条目。

\documentclass{article}
\usepackage{listofitems}
\newcommand\z[2]{%
  \readlist*\student{#2}%
  First argument: #1.\par
  \ifnum\studentlen=1\relax%
    Only one name provided: \student[1]%
  \else%
    Two names provided: \student[1] and \student[2]%
  \fi%
}
\begin{document}
\z{A}{B}

\z{A}{B,C}
\end{document}

在此处输入图片描述

答案2

您是否知道在 TeX/LaTeX 中由单个标记组成的未限定参数不需要嵌套在括号中?

定义后\newcommand\foo[1]{This is argument 1: #1.}
\foo{b}将产生与相同的结果
\foo b

定义之后\newcommand\foo[2]{This is argument 1: #1. This is argument 2: #2.},以下调用都会产生相同的结果:
\foo{a}{b}
\foo a{b}
\foo {a}b
\foo ab
\foo{a} {b}
\foo a {b}
\foo {a} b
\foo a b

这是因为

  1. 当未限定的参数由单个标记组成时,不需要括号。
  2. (La)TeX 确实会丢弃未限定参数前面的空格标记。

当被调用时 \mycomm{a}{b}c——如何\mycomm“知道”用户是否打算使用c\mycomm单个标记组成的第三个参数c,或者用户是否打算\mycomm仅使用两个参数进行调用,即{a}{b}而不应c被视为第三个参数?

形势很不明朗。

\mycomm你可以通过只处理一个未限定的参数并\mycomm检查该参数是否属于其中一种模式,从而将情况变得明确

{⟨argument 1⟩}

{⟨argument 1⟩}{⟨argument 2⟩}

{⟨argument 1⟩}{⟨argument 2⟩}{⟨argument 3⟩}

...

{⟨argument 1⟩}{⟨argument 2⟩}{⟨argument 3⟩}...{⟨argument k⟩}

\mycomm如果检测到其中一种模式,则采取相应行动,\mycomm否则发出错误消息。

IE,

\mycomm{{⟨argument 1⟩}}

\mycomm{{⟨argument 1⟩}{⟨argument 2⟩}}

\mycomm{{⟨argument 1⟩}{⟨argument 2⟩}{⟨argument 3⟩}}

...

\mycomm{{⟨argument 1⟩}{⟨argument 2⟩}{⟨argument 3⟩}...{⟨argument k⟩}}

昨天我回答了一个和你类似的问题,主题:如何定义具有两个可选参数的命令?,并提供了一个使用最多三个参数执行此操作的示例。

您可以使用相同的策略轻松调整该示例,以检测最多九个参数。

但是在您的场景中,情况是关于用户可能会提供特定的数据,最好有一个键值接口,以便用户可以通过逗号分隔的键值列表传递她喜欢的数据,因此敦促通过提供不仅值而且还提供键来指定她希望提供的数据。

用户可以使用以下东西:

\homeworkdata[FirstName=Jason, LastName=Smith]{1}{2}{3}{4}
表明使用了该用户的名称。

\homeworkdata[LastName=Smith, FirstName=Jason]{1}{2}{3}{4}
表明使用了该用户的名称。

\homeworkdata{1}{2}{3}{4}
结果使用默认值“First name”和“Last name”。

有很多软件包提供了实现 key-val 语法的方法:

https://ctan.org/topic/keyval

使用这些包,您可以提供默认值,以防用户未指定其他值。对于密钥,FirstName您可以指定默认值First name,对于密钥,LastName您可以指定默认值Last name

相关内容