根据第一个链接,我所面临的参数数量是有限的。
我尝试使用指定的方法并且效果很好。
但是如果我想要超过 18 个参数怎么办?
是否可以递归使用这种方法?
例如,我想定义一个有 25 个参数的函数。是否可以使用以下方法:
\newcommand\ParseOptMenuItemStoreA[9]{%
\def\tempa{#1}%
\def\tempb{#2}%
\def\tempc{#3}%
\def\tempd{#4}%
\def\tempe{#5}%
\def\tempf{#6}%
\def\tempg{#7}%
\def\temph{#8}%
\def\tempi{#9}%
\ParseOptMenuItemStoreB
}
\newcommand\ParseOptMenuItemStoreB[9]{%
\def\tempj{#1}%
\def\tempk{#2}%
\def\templ{#3}%
\def\tempm{#4}%
\def\tempn{#5}%
\def\tempo{#6}%
\def\tempp{#7}%
\def\tempq{#8}%
\def\tempr{#9}%
\ParseOptMenuItem
}
\newcommand\ParseOptMenuItem[7]{%
% Access to arguments #1-#18 via \tempa-\tempr and to argument #19-#25 via #1-#7.
}
我尝试编译它但出现错误:
! Missing number, treated as zero.
<to be read again>
\protect
l.40 }
那么我做错了什么?
2015 年 8 月 19 日更新:
我使用了下一个构造来实现我的目标:
\newcommand{\ParseOptMenuItemList}[1]
{
\def\tmplist{#1}%
\@tempcnta=\z@
\@for\tmp:=\tmplist\do{\advance\@tempcnta\@ne
\expandafter\let\csname temp\@roman\@tempcnta\endcsname\tmp
}%
\makebox[\linewidth][r]{%
\begin{tabular}{lc}
Possible values: \ifthenelse{\equal{\tempi}{}}{}{& \tempi\\}
\ifthenelse{\equal{\tempii}{}}{}{& \tempii\\}
\ifthenelse{\equal{\tempiii}{}}{}{& \tempiii\\}
\ifthenelse{\equal{\tempiv}{}}{}{& \tempiv\\}
\ifthenelse{\equal{\tempv}{}}{}{& \tempv\\}
\ifthenelse{\equal{\tempvi}{}}{}{& \tempvi\\}
\ifthenelse{\equal{\tempvii}{}}{}{& \tempvii\\}
\ifthenelse{\equal{\tempviii}{}}{}{& \tempviii\\}
\ifthenelse{\equal{\tempix}{}}{}{& \tempix\\}
\ifthenelse{\equal{\tempx}{}}{}{& \tempx\\}
\ifthenelse{\equal{\tempxi}{}}{}{& \tempxi\\}
\ifthenelse{\equal{\tempxii}{}}{}{& \tempxii\\}
\ifthenelse{\equal{\tempxiii}{}}{}{& \tempxiii\\}
\ifthenelse{\equal{\tempxiv}{}}{}{& \tempxiv\\}
\ifthenelse{\equal{\tempxv}{}}{}{& \tempxv\\}
\ifthenelse{\equal{\tempxvi}{}}{}{& \tempxvi\\}
\ifthenelse{\equal{\tempxvii}{}}{}{& \tempxvii\\}
\ifthenelse{\equal{\tempxviii}{}}{}{& \tempxviii\\}
Default value: & \tempxix\\
\end{tabular}
}
}
\ParseOptMenuItemList
将值作为逗号分隔的列表。
答案1
与所有其他 Latex 命令不同,使用多个{}
会导致界面难以使用,Latex 具有将参数处理为逗号分隔列表的标准功能(\usepackage{array,bm,graphics}
例如)。
生成以下内容
argument 24 is: [x]
在终端上确认已捕获参数 24(至少:-)。
\makeatletter
\newcommand\foo[1]{%
\def\tmplist{#1}%
\@tempcnta=\z@
\@for\tmp:=\tmplist\do{\advance\@tempcnta\@ne
\expandafter\let\csname temp\@roman\@tempcnta\endcsname\tmp
}%
\typeout{argument 24 is: [\tempxxiv]}%
}
\makeatother
\foo{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}
\stop
答案2
这是另一个,您必须调用这个\definemanyarguments{24}
,然后接下来的 24 个参数将被“保存”,然后您可以使用它们\argument{12}
。
这是完整的文档。
\documentclass{scrartcl}
\newcounter{manyarguments}
\providecommand\gobbleone[1]{}
\providecommand\useone[1]{#1}
\newcommand*\definemanyarguments[1]
{\setcounter{manyarguments}{0}%
\def\nextargument{\stepcounter{manyarguments}%
\ifnum\value{manyarguments}>#1 \expandafter\gobbleone
\else\expandafter\useone\fi
{\afterassignment\nextargument
\csdefignorespaces{argumentnumber\arabic{manyarguments}}}}%
\nextargument}
\newcommand\csdefignorespaces[2]{\expandafter\def\csname#1\endcsname{#2}}
\newcommand*\argument[1]{\csname argumentnumber#1\endcsname}
\begin{document}
\definemanyarguments{25}
{1}{2}{3}{4}{5}{6}{7}{8}{9}{a}{b}{c}{d}{e}{f}{g}{h}{i}
{A}{B}{C}{D}{E}{F}{last argument}
[\argument{2}]
[\argument{12}]
[\argument{23}]
[\argument{24}]
[\argument{25}]
\end{document}
答案3
我认为使用带有超过三或四个参数的宏是没有道理的。但是,这里有一个\newextracommand
可以接受任意数量参数的实现(受 TeX 的算术能力限制,因此不超过 2 30 –1,当然也受内存限制)。
\documentclass{article}
\newcommand\newextracommand[3]{%
\newcounter{extra\string#1}%
\newcommand{#1}{\extrarecurse{#1}{#2}{#3}}%
}
\newcommand\extrarecurse[3]{%
\setcounter{extra\string#1}{1}%
\grabarg{#1}{#2}{#3}%
}
\makeatletter
\newcommand{\grabarg}[4]{%
\ifnum#2<\value{extra\string#1}\relax
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi
{%
\@namedef{arg@\romannumeral\value{extra\string#1}}{#4}
\stepcounter{extra\string#1}%
\grabarg{#1}{#2}{#3}
}
{#3}%
}
\newcommand\doarg[1]{\csname arg@\romannumeral#1\endcsname}
\makeatother
\newextracommand{\foo}{20}{%
\doarg{1}--\doarg{2}--\doarg{3}--\doarg{4}--%
\doarg{5}--\doarg{6}--\doarg{7}--\doarg{8}--%
\doarg{9}--\doarg{10}--\doarg{11}--\doarg{12}--%
\doarg{13}--\doarg{14}--\doarg{15}--\doarg{16}--%
\doarg{17}--\doarg{18}--\doarg{19}--\doarg{20}%
}
\begin{document}
\foo{a}{b}{c}{d}{e}{f}{g}{h}{i}{j}{k}{l}{m}{n}{o}{p}{q}{r}{s}{t}
\end{document}
定义主体中的参数用 表示\doarg{<number>}
。
不要尝试在表格单元格中使用此类命令,也不要尝试嵌套调用如此定义的相同命令。
答案4
它似乎对我有用:
\documentclass{article}
\newcommand\ParseOptMenuItemStoreA[9]{%
\def\tempa{#1}%
\def\tempb{#2}%
\def\tempc{#3}%
\def\tempd{#4}%
\def\tempe{#5}%
\def\tempf{#6}%
\def\tempg{#7}%
\def\temph{#8}%
\def\tempi{#9}%
\ParseOptMenuItemStoreB
}
\newcommand\ParseOptMenuItemStoreB[9]{%
\def\tempj{#1}%
\def\tempk{#2}%
\def\templ{#3}%
\def\tempm{#4}%
\def\tempn{#5}%
\def\tempo{#6}%
\def\tempp{#7}%
\def\tempq{#8}%
\def\tempr{#9}%
\ParseOptMenuItem
}
\newcommand\ParseOptMenuItem[7]{%
% Access to arguments #1-#18 via \tempa-\tempr and to argument #19-#25 via #1-#7.
before
#7
tempj: \tempj
tempi: \tempi
after
}
\begin{document}
\ParseOptMenuItemStoreA{1}{2}{3}{4}{5}{6}{7}{8}{9}{a}{b}{c}{d}{e}{f}{g}{h}{i}{A}{B}{C}{D}{E}{F}{last argument}
\end{document}
但你可能不应该这么做,理由 David Carlisle 和 Christian Hupfer 已经给出了。