如何访问宏的第 i 个参数?

如何访问宏的第 i 个参数?

如何\newcommand通过迭代变量访问声明的第 i 个参数?

假设我想要如下命令\foo

\newcommand{\barr}[1]{argument 1 is: #1}

\newcommand{\foo}[6]{
    \foreach \i in {1,...,6}
        \barr{#\i}; %this does not work. \barr{#1}, \barr{#6} do work
}

编辑:根据要求,提供一些背景信息。我想要一个命令,比如\foo{1}{2}{5}{0}{1}{2}在第一部分画 1 个球,在第二部分画 2 个球,在第三部分画 5 个球,等等。一切正常,我唯一缺少的是以方便的方式访问第 i 个参数。

答案1

\whiledo对于\foreachOP 来说,这可能被接受,也可能不被接受。

\documentclass{article}
\usepackage{stringstrings}
\newcounter{index}
\newcommand{\barr}[2]{argument #1 is: #2\par}
\newcommand\foo[1]{%
  \getargs{#1}%
  \setcounter{index}{0}%
  \whiledo{\theindex < \narg}{%
    \stepcounter{index}%
    \barr{\theindex}{\csname arg\romannumeral\theindex\endcsname}%
  }%
}
\begin{document}
\foo{A B C D EE F GGG H I JJJ K FinalArgument}
\end{document}

答案2

您不能以那种方式指定宏;#1#2等等必须在定义时确实存在,因为它们代表占位符。


我不明白为什么要限制为六个:对于五个或八个,你可能需要相同的数量。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\foo}{ O{,} m}
 {
  \mort_add_bar:nn { #1 } { #2 }
 }

\seq_new:N \l_mort_input_seq
\seq_new:N \l_mort_output_seq
\cs_new_protected:Npn \mort_add_bar:nn #1 #2
 {
  % split the input at the comma (or what's in the optional argument)
  \seq_set_split:Nnn \l_mort_input_seq { #1 } { #2 }
  % clear the output section
  \seq_clear:N \l_mort_output_seq
  % put each item inside \bar{...}
  \seq_map_inline:Nn \l_mort_input_seq
   {
    \seq_put_right:Nn \l_mort_output_seq { \bar{ ##1 } }
   }
  % output the sequence, separated by semicolons
  \seq_use:Nn \l_mort_output_seq { ; }
 }
\ExplSyntaxOff

\begin{document}
$\foo{a,b,c}$

% just to show that you can change the
% delimiter and have as many items as you wish
$\foo[.]{a.b.c.e.f.g.h.i}$ 
\end{document}

在此处输入图片描述

为了绘制多个对象,这里有一个可能的解决方案:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\foo}{ O{,} m }
 {
  \mort_add_bar:nn { #1 } { #2 }
 }

\seq_new:N \l_mort_input_seq
\cs_new_protected:Npn \mort_add_bar:nn #1 #2
 {
  \seq_set_split:Nnn \l_mort_input_seq { #1 } { #2 }
  \seq_map_inline:Nn \l_mort_input_seq
   {
    \mort_draw_balls:n { ##1 }
   }
 }
\cs_new_protected:Npn \mort_draw_balls:n #1
 {
  /
  \prg_replicate:nn { #1 } { \textbullet }
  /
 }

\ExplSyntaxOff

\begin{document}
\foo{1,2,5,0,1,2}

% just to show that you can change the
% delimiter and have as many items as you wish
\foo[-]{1-3-4}
\end{document}

在此处输入图片描述

答案3

egreg 和 Steven B. Segletes 的解决方案当然很棒。但是,如果参数数量固定,那么这似乎有点过头了。

另外,这个也可以:

\newcommand{\bar}[1]{argument 1 is: #1}

\newcommand{\foo}[6]{
\foreach \i/\j in {1/#1,2/#2,3/#3,4/#4,5/#5,6/#6}   
    \putinbin{\i}{\j};
}

答案4

我认为 TeX-core 无法以简单的方式实现这一点。最简单的方法可能是以下方法,但它既不美观也不高效,因为你必须输入正确的项数(否则 TeX-core 会抱怨参数无效)。

\newcommand{\bar}[1]{argument 1 is: #1}

\newcommand{\foo}[6]{
    \foreach \i in {1,...,6}
        \bar{\ifcase\i\or#1\or#2\or#3\or#4\or#5\or#6\fi};
}

相关内容