我知道如何使用\newif
and在 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
这是因为
- 当未限定的参数由单个标记组成时,不需要括号。
- (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 语法的方法:
使用这些包,您可以提供默认值,以防用户未指定其他值。对于密钥,FirstName
您可以指定默认值First name
,对于密钥,LastName
您可以指定默认值Last name
。