如何\cmd
使用两个可选参数(和一个强制参数)在 TeX 基元中定义一个宏,以满足调用\cmd[opt]{mand}
等同于 的属性\cmd[][opt]{mand}
。然而,我只能创建这个宏,使其\cmd[opt]{mand}
等同于\cmd[opt][]{mand}
。我真的不明白我必须向 TeX 提出什么样的问题才能实现我的想法。你有什么建议吗?
答案1
这是一种方法,尽管不清楚您真正想要实现什么。
\long\def\firstoftwo#1#2{#1}
\long\def\secondoftwo#1#2{#2}
\def\cmd{\futurelet\next\cmdi}
\def\cmdi{%
\ifx\next[%
\expandafter\firstoftwo
\else
\expandafter\secondoftwo
\fi
{\cmdopt}%
{\cmdx[][]}%
}
\def\cmdopt[#1]{\def\firstopt{#1}%
\futurelet\next\cmdoptii}
\def\cmdoptii{%
\ifx\next[%
\expandafter\firstoftwo
\else
\expandafter\secondoftwo
\fi
{\expandafter\cmdx\expandafter[\firstopt]}%
{\expandafter\cmdx\expandafter[\expandafter]\expandafter[\firstopt]}%
}
\def\cmdx[#1][#2]#3{%
\par\noindent{\tt\string\cmd} called with:\par
first optional argument=#1;\par
second optional argument=#2;\par
mandatory argument=#3\par}
\cmd{abc}
\cmd[opt1]{abc}
\cmd[opt1][opt2]{abc}
\bye
答案2
这是一种实现我认为你想要的方法
包裹xparse
:
笔记:
\{
在实际使用中,您需要将and替换\}
为{
and}
。我使用转义版本来生成输出。
代码:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\MyCommand}{o o m}{%
\IfNoValueTF{#1}{%
Command\{#3\}% No optional parameters specified
}{%
% Optional parameters specified.
% Now need to check if #2 was provided.
\IfNoValueTF{#2}{%
Command[ ][#1]\{#3\}% #2 NOT provided
}{%
Command[#1][#2]\{#3\}% Both #1 and #2 provided.
}%
}%
}
\begin{document}
\MyCommand{no optional paramters}
\MyCommand[optional param1]{one optional paramater}
\MyCommand[optional param1][optional param2]{two optional paramaters}
\end{document}
答案3
好的,我们已经得到了问题纯文本回答来自埃格尔,我们有两个相当令人困惑的 LaTeX3/解析来自的答案彼得·格里尔和沃纳;我也会把我的 LaTeX2 解决方案扔进帽子里。
它用\kernel@ifnextchar
。
代码
\documentclass{article}
\makeatletter
% a)
%\newcommand*{\cmd}[1][]{\kernel@ifnextchar[{\cmd@@[{#1}]}{\cmd@@[][{#1}]}}
% or b)
\def\cmd{\kernel@ifnextchar[\cmd@{\cmd@[]}}
\def\cmd@[#1]{\kernel@ifnextchar[{\cmd@@[{#1}]}{\cmd@@[][{#1}]}}
% a) and b)
\def\cmd@@[#1][#2]#3{opt 1 $\to$ \texttt{#1}; opt 2 $\to$ \texttt{#2}; man $\to$ \texttt{#3}\par}
\makeatother
\begin{document}
\cmd{abc} % -> \cmd@@[][]{abc}
\cmd[opt1]{abc} % -> \cmd@@[][opt1]{abc}
\cmd[opt1][opt2]{abc} % -> \cmd@@[opt1][opt2]{abc}
\end{document}
输出
答案4
以下是基于这个很好的答案。基本上,您使用两个\newcommand
带有一个可选参数的 s,并让其中一个调用另一个。区分第二个是缺失还是存在但为空有点复杂;我(相当笨拙地)窃取了 LaTeX3 方法,将其用作-NoValue-
前者的指标,因此下面的第二个和第四个示例返回不同的结果。
\documentclass{article}
\usepackage{etoolbox}
\newcommand*\cmd[1][]{%
\def\argi{#1}%
\cmdA
}
% Default stolen from LaTeX3, badly
\newcommand*\cmdA[2][-NoValue-]{%
\def\argii{#1}%
\ifdefstring{\argii}{-NoValue-}{%
\let\argii\argi
\let\argi\empty
}{}%
Arg 1: \argi,
Arg 2: \argii,
Mandatory arg: #2%
}
\begin{document}
\cmd{x}
\cmd[a]{x}
\cmd[][a]{x}
\cmd[a][]{x}
\cmd[a][b]{x}
\end{document}