如何定义具有可变数量参数的新命令?

如何定义具有可变数量参数的新命令?

我想创建具有如下功能的新命令(伪代码):

\newcommand{\myCommand}[numOfParameters]  { 
  for (i = 0; i < numOfParameters / 3; i++) {
     \somecommand1{#(i*3 + 1)}
     \somecommand1{#(i*3 + 2)}
     \somecommand1{#(i*3 + 3)}
  }
}

是否可以在 LaTeX 中实现这样的功能?

以下是使用示例(根据要求):

这是一个宏,每行显示 2 张图片......

\newcommand{\twoimages}[6] {
    \begin{figure}[htb!]
        \begin{minipage}[h]{0.49\linewidth}
            \begin{center}
                \includegraphics[width=#3\linewidth]{#1} \\ 
                \caption{#2} 
                \label{ris:#1}
            \end{center}
        \end{minipage}
        \hfill
        \begin{minipage}[h]{0.49\linewidth}
            \begin{center}
                \includegraphics[width=#6\linewidth]{#4} \\ 
                \caption{#5}
                \label{ris:#4}
            \end{center}
        \end{minipage}
    \end{figure}
}

我想为 N(用户定义的数量)图像制作宏

答案1

您可以定义递归宏,这些宏会不断调用自身,直到找到终止点;您的问题的解决方案如下:

\makeatletter % we need to use kernel commands
\newcommand{\twoimages}{%
  \begin{figure}[!htb]
  \@twoimagesi
}
\newcommand\@twoimagesi{\@ifnextchar\stopimages{\@twoimagesend}{\@twoimagesii}}

\newcommand\@twoimagesii[6]{%
  \@twoimagesiii{#1}{#2}{#3}\hfill
  \@twoimagesiii{#4}{#5}{#6}\\[\bigskipamount]
  \@twoimagesi % restart the recursion
}
\newcommand\@twoimagesiii[3]{%
  \begin{minipage}{0.49\linewidth}
    \centering
    \includegraphics[width=#3\linewidth]{#1}
    \caption{#2}\label{ris:#1}
  \end{minipage}}
\newcommand\@twoimagesend[1]{% The argument is \stopimages
  \vspace*{-\bigskipamount}
  \end{figure}}
\makeatother

\twoimages实际上没有参数;它只是通过打开环境来启动业务figure并调用真正的命令\@twoimagesi。此命令检查它后面是否跟着\stopimages;如果是,它调用\@twoimagesend它来结束环境;否则它在吸收了它的六个参数后执行打印一行的任务。它以间接的方式执行此操作,因此我们只需使用前三个参数和后三个参数\@twoimagesii编写一次相同的。minipage

然后\@twoimagesii通过再次调用重新开始递归\@twoimagesi


让我们看一个完整的例子(我使用绘制黑色斑点而不是需要外部文件的demo选项)。graphicx

\documentclass{article}
\usepackage[demo]{graphicx}

\makeatletter % we need to use kernel commands
\newcommand{\twoimages}{%
  \begin{figure}[!htb]
  \@twoimagesi
}
\newcommand\@twoimagesi{\@ifnextchar\stopimages{\@twoimagesend}{\@twoimagesii}}

\newcommand\@twoimagesii[6]{%
  \@twoimagesiii{#1}{#2}{#3}\hfill
  \@twoimagesiii{#4}{#5}{#6}\\[\bigskipamount]
  \@twoimagesi % restart the recursion
}
\newcommand\@twoimagesiii[3]{%
  \begin{minipage}{0.49\linewidth}
    \centering
    \includegraphics[width=#3\linewidth]{#1}
    \caption{#2}\label{ris:#1}
  \end{minipage}}
\newcommand\@twoimagesend[1]{% The argument is \stopimages
  \vspace*{-\bigskipamount}
  \end{figure}}
\makeatother

\begin{document}
\twoimages
  {a}{Caption left}{.5}
  {b}{Caption right}{.5}
  {c}{Caption left}{.5}
  {d}{Caption right}{.5}
\stopimages
\end{document}

在此处输入图片描述


一种完全不同的方法是通过expl3宏。语法也会有所不同;我将给出一个几乎不言自明的示例:主宏在逗号处拆分其参数,并且每个块的处理方式与以前非常相似。

\documentclass{article}
\usepackage[demo]{graphicx}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\twoimages}{ >{ \SplitList {,} } m }
 {
  \begin{figure}[!htb]
  \centering
  \ProcessList { #1 } { \davs__twoimages_row:n }
  \vspace{-\bigskipamount}
  \end{figure}
 }
\cs_new_protected:Nn \davs__twoimages_row:n
 {
  \davs__twoimages_row:nnnnnn #1
 }
\cs_new_protected:Nn \davs__twoimages_row:nnnnnn
 {
  \davs__twoimages_do:nnn { #1 } { #2 } { #3 } 
  \hfill
  \davs__twoimages_do:nnn { #4 } { #5 } { #6 }
  \\[\bigskipamount]
 }
\cs_new_protected:Nn \davs__twoimages_do:nnn
 {
  \begin{minipage}{0.49\linewidth}
    \centering
    \includegraphics[width=#3\linewidth]{#1}
    \caption{#2}\label{ris:#1}
  \end{minipage}
 }
\ExplSyntaxOff
\begin{document}

\twoimages{
  {a}{Caption left}{.5}
  {b}{Caption right}{.5},
  {c}{Caption left}{.5}
  {d}{Caption right}{.5}
}

\end{document}

结果与之前完全相同。可以有任意数量的六元组参数,以逗号分隔。


只是为了完整性,版本可以接受任意数量的图像;现在每个三元组应该用逗号分隔;如果图像数量是奇数,则最后一幅将居中。

\documentclass{article}
\usepackage[demo]{graphicx}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\twoimages}{ >{ \SplitList {,} } m }
 {
  \begin{figure}[!htb]
  \centering
  \leftskip=\fill \rightskip=\fill
  \lineskip=\baselineskip % to compensate for the minipages
  \ProcessList { #1 } { \__davs_process_argument:n }
  \end{figure}
 }
\cs_new_protected:Nn \__davs_process_argument:n
 {
  \__davs_image:nnn #1
 }
\cs_new_protected:Nn \__davs_image:nnn
 {
  \hspace*{\fill}
  \begin{minipage}{0.49\linewidth}
    \centering
    \includegraphics[width=#3\linewidth]{#1}
    \caption{#2}\label{ris:#1}
  \end{minipage}
  \hspace*{\fill}
  \penalty0 % we provide a break point
 }
\ExplSyntaxOff
\begin{document}

\twoimages{
  {a}{Caption left}{.5},
  {b}{Caption right}{.5},
  {c}{Caption left}{.5},
  {d}{Caption right}{.5},
  {e}{Caption center}{.5}
}

\end{document}

答案2

以下示例使用在命令的参数中给出参数的语法:\images{{...}{...}{...}{...}{...}{...}...}。然后宏\images解析其参数并一次捕获三个参数:

\documentclass{article}

\newif\ifimagesSep
\newcommand*{\images}[1]{%
  \par\noindent[begin images]\\\relax
  \imagesSepfalse
  \imagesScan#1\relax\relax\relax
  [end images]\par
}
\newcommand{\imagesScan}[3]{%
  \ifx\relax#1\empty
  \else
    \ifimagesSep
      [separation]\\\relax
    \else
      \imagesSeptrue
    \fi
    [image: #1 #2 #3]\\\relax
    \expandafter\imagesScan
  \fi
}

\begin{document}

\images{
  {w1}{l1}{c1}
  {w2}{l2}{c2}
  {w3}{l3}{c3}
}
\end{document}

结果

答案3

\WrapKArgsBetweenTokens我刚刚编写了一个由扩展驱动的宏\romannumeral,因此在两个扩展步骤后即可提供结果。

句法:

\WrapKArgsBetweenTokens{%
  ⟨TeX-⟨number⟩-quantity of value K⟩
}{%
  ⟨tokens in case of error, 
   i.e., in case 
   amount of arguments with tokens to prepend 
   =/=
   amount of arguments with tokens to append⟩
}{%
  {⟨tokens to prepend to ⟨argument i⟩ in case i == 1 (mod n)⟩}% <- case 1
  {⟨tokens to prepend to ⟨argument i⟩ in case i == 2 (mod n)⟩}% <- case 2
  ... 
  {⟨tokens to prepend to ⟨argument i⟩ in case i == n (mod n)⟩}% <- case n
}{%
  {⟨tokens to append to ⟨argument i⟩ in case i == 1 (mod n)⟩}% <- case 1
  {⟨tokens to append to ⟨argument i⟩ in case i == 2 (mod n)⟩}% <- case 2
  ... 
  {⟨tokens to append to ⟨argument i⟩ in case i == n (mod n)⟩}% <- case n
}%
{⟨argument 1⟩}%
{⟨argument 2⟩}%
...
{⟨argument K⟩}%

如果模式的参数数量

{⟨tokens to prepend to ⟨argument i⟩ in case i == m (mod n)⟩}% <- case m

不等于模式的参数数量

{⟨tokens to append to ⟨argument i⟩ in case i == m (mod n)⟩}% <- case m

你得到

⟨tokens in case of error, i.e., in case  amount of arguments with tokens to prepend =/= amount of arguments with tokens to append&rangle

{⟨argument 1⟩}%
{⟨argument 2⟩}%
...
{⟨argument K⟩}%
不是从标记流中收集的。

 

K否则,将从标记流中收集大量后续未限定的参数,您将得到以下结果:

⟨tokens to prepend to ⟨argument i⟩ in case i == 1 (mod n)⟩%
{⟨argument 1⟩}%
⟨tokens to append to ⟨argument i⟩ in case i == 1 (mod n)⟩%
⟨tokens to prepend to ⟨argument i⟩ in case i == 2 (mod n)⟩%
{⟨argument 2⟩}%
⟨tokens to append to ⟨argument i⟩ in case i == 2 (mod n)⟩%
...
⟨tokens to prepend to ⟨argument i⟩ in case i == n (mod n)⟩%
{⟨argument n⟩}%
⟨tokens to append to ⟨argument i⟩ in case i == n (mod n)⟩%
⟨tokens to prepend to ⟨argument i⟩ in case i == 1 (mod n)⟩%
{⟨argument n+1⟩}%
⟨tokens to append to ⟨argument i⟩ in case i == 1 (mod n)⟩%
⟨tokens to prepend to ⟨argument i⟩ in case i == 2 (mod n)⟩%
{⟨argument n+2⟩}%
⟨tokens to append to ⟨argument i⟩ in case i == 2 (mod n)⟩%
...
⟨tokens to prepend to ⟨argument i⟩ in case i == ... (mod n)⟩%
{⟨argument K⟩}%
⟨tokens to append to ⟨argument i⟩ in case i == ... (mod n)⟩%
\errorcontextlines=10000
\documentclass[a4paper]{article}
%===================[adjust margins/layout for the example]====================
\csname @ifundefined\endcsname{pagewidth}{}{\pagewidth=\paperwidth}%
\csname @ifundefined\endcsname{pdfpagewidth}{}{\pdfpagewidth=\paperwidth}%
\csname @ifundefined\endcsname{pageheight}{}{\pageheight=\paperheight}%
\csname @ifundefined\endcsname{pdfpageheight}{}{\pdfpageheight=\paperheight}%
\textwidth=\paperwidth
\oddsidemargin=1.25cm
\marginparsep=.2\oddsidemargin
\marginparwidth=\oddsidemargin
\advance\marginparwidth-2\marginparsep
\advance\textwidth-2\oddsidemargin
\advance\oddsidemargin-1in
\evensidemargin=\oddsidemargin
\textheight=\paperheight
\topmargin=1.25cm
\footskip=.5\topmargin
{\normalfont\global\advance\footskip.5\ht\strutbox}%
\advance\textheight-2\topmargin
\advance\topmargin-1in
\headheight=0ex
\headsep=0ex
\pagestyle{plain}
\parindent=0ex
\parskip=0ex 
\topsep=0ex
\partopsep=0ex
%==================[eof margin-adjustments]====================================
%==================[Print long lines nicely]===================================
\usepackage{seqsplit}
\newcommand\PRINTtempa{%

  \noindent
  \textit{yields:}

  \noindent
  {%
    \ttfamily
    \string\tempa=%
    \expandafter\seqsplit\expandafter{\meaning\tempa}%
  }%
}%
\makeatother
%==================[Eof print long lines nicely]===============================


\makeatletter
%% Code for \ExtractKthArg:
%%=============================================================================
%% Paraphernalia:
%%    \UD@firstoftwo, \UD@secondoftwo, \UD@PassFirstToSecond, \UD@Exchange,
%%    \UD@stopromannumeral, \UD@CheckWhetherNull
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral\expandafter\UD@secondoftwo\string{\expandafter
  \UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
  \UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{%
  \expandafter\UD@stopromannumeral\UD@firstoftwo}%
}%
%%=============================================================================
%% Extract K-th inner undelimited argument:
%%
%% \ExtractKthArg{<integer K>}%
%%               {<tokens in case list of undelimited args doesn't have a k-th argument>}%
%%               {<list of undelimited args>}%
%% 
%% In case there is no K-th argument in <list of indelimited args> : 
%%   Does deliver <tokens in case list of undelimited args doesn't have a k-th argument.
%% In case there is a K-th argument in <list of undelimited args> : 
%%   Does deliver that K-th argument with one level of braces removed.
%%
%% Examples:
%%
%%   \ExtractKthArg{0}{not available}{ABCDE} yields: not available
%%
%%   \ExtractKthArg{3}{not available}{ABCDE} yields:  C
%%
%%   \ExtractKthArg{3}{not available}{AB{CD}E} yields:  CD
%%
%%   \ExtractKthArg{4}{not available}{{001}{002}{003}{004}{005}} yields: 004
%%
%%   \ExtractKthArg{6}{not available}{{001}{002}{003}} yields: not available 
%% 
%%=============================================================================
\newcommand\ExtractKthArg[2]{%
  \romannumeral%
  % #1: <integer number K>
  % #2: <action if there is no K-th argument>
  \expandafter\UD@ExtractKthArgCheck
  \expandafter{\romannumeral\number\number#1 000}{#2}%
}%
\newcommand\UD@ExtractKthArgCheck[3]{%
  \UD@CheckWhetherNull{#1}{\UD@stopromannumeral#2}{% empty
    \expandafter\UD@ExtractKthArgLoop\expandafter{\UD@firstoftwo{}#1}{#2}{#3}%
  }%
}%
\begingroup
\def\UD@ExtractFirstArgLoop#1{%
  \endgroup
  \@ifdefinable\UD@RemoveTillFrozenrelax{%
    \long\def\UD@RemoveTillFrozenrelax##1##2#1{{##1}}%
  }%
  \newcommand\UD@ExtractKthArgLoop[3]{%
    \expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo##3{}.}{\UD@stopromannumeral##2}{%
      \UD@CheckWhetherNull{##1}{%
        \UD@ExtractFirstArgLoop{##3#1}%
      }{%
        \expandafter\UD@PassFirstToSecond\expandafter{\UD@firstoftwo{}##3}%
        {\expandafter\UD@ExtractKthArgLoop\expandafter{\UD@firstoftwo{}##1}{##2}}%
      }%
    }%
  }%
}%
\expandafter\expandafter\expandafter\UD@ExtractFirstArgLoop
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\ifnum0=0\fi}%
%% Usage of frozen-\relax as delimiter is for speeding things up by reducing the
%% amount of iterations needed. I chose frozen-\relax because David Carlisle 
%% pointed out in   <https://tex.stackexchange.com/a/578877>
%% that frozen-\relax cannot be (re)defined in terms of \outer and cannot be
%% affected by \uppercase/\lowercase.
%%
%% \UD@ExtractFirstArg's argument may contain frozen-\relax:
%% The only effect is that internally more iterations are needed for
%% obtaining the result.
\newcommand\UD@ExtractFirstArgLoop[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
  {\expandafter\UD@stopromannumeral\UD@firstoftwo#1{}}%
  {\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillFrozenrelax#1}}%
}%
%% End of code for \ExtractKthArg.
%% Code for \WrapKArgsBetweenTokens:
%%=============================================================================
%% Wrap K undelimited macro arguments between tokens
%%-----------------------------------------------------------------------------
%%
%% Syntax:
%% 
%% \WrapKArgsBetweenTokens{%
%%    <TeX-<number>-quantity of value K>
%% }{%
%%   <Tokens in case of error, i.e., 
%%    in case amount of arguments with tokens to prepend =/= 
%%    amount of arguments with tokens to append>
%% }{%
%%   {<Tokens to prepend to <argument i> in case i == 1 (mod n)>}% <- case 1
%%   {<Tokens to prepend to <argument i> in case i == 2 (mod n)>}% <- case 2
%%   ... 
%%   {<Tokens to prepend to <argument i> in case i == n (mod n)>}% <- case n
%% }{%
%%   {<Tokens to append to <argument i> in case i == 1 (mod n)>}% <- case 1
%%   {<Tokens to append to <argument i> in case i == 2 (mod n)>}% <- case 2
%%   ... 
%%   {<Tokens to append to <argument i> in case i == n (mod n)>}% <- case n
%% }%
%% {<argument 1>}{<argument 2>}...{<argument K>}
%%=============================================================================
\newcommand\WrapKArgsBetweenTokens[4]{%
  \romannumeral
  \UD@WrapKArgsBetweenTokensCountcasesloop{#3}{#4}{}%
    {\UD@stopromannumeral#2}%
    {%
      \expandafter\UD@WrapKArgsBetweenTokensLoopStart
      \expandafter{\romannumeral\number\number#1 000}{#3}{#4}%
    }%
}%
%===========================================================================
\newcommand\UD@WrapKArgsBetweenTokensCountcasesloop[3]{%
  % #1 - <remaining prepend cases>
  % #2 - <remaining append cases>
  % #3 - <amount of m>
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo#1{}{}}{%
    \expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo#2{}{}}{%
      \expandafter\UD@PassFirstToSecond\UD@firstoftwo{{#3}}%
    }{%
      \UD@firstoftwo
    }%
  }{%
    \expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo#2{}{}}{%
      \UD@firstoftwo
    }{%
      \expandafter\UD@PassFirstToSecond\expandafter{\UD@firstoftwo{}#2}{%
        \expandafter\UD@WrapKArgsBetweenTokensCountcasesloop
        \expandafter{\UD@firstoftwo{}#1}%
      }{#3m}%
    }%
  }%
}%
%===========================================================================
\newcommand\UD@WrapKArgsBetweenTokensLoopStart[4]{%
  % #1 - <m in amount of args still to gather>
  % #2 - <prepend cases>
  % #3 - <append cases>
  % #4 - <m in amount of modulo-cases>
  \UD@CheckWhetherNull{#4}{%
    \UD@WrapKArgsBetweenTokensLoopCheckEnd{#2}{#3}{m}{}{#1}{m}{m}%
  }{%
    \UD@WrapKArgsBetweenTokensLoopCheckEnd{#2}{#3}{#4}{}{#1}{#4}{m}%
  }%
}%
\newcommand\UD@WrapKArgsBetweenTokensLoopCheckEnd[7]{%
  % #1 - <prepend cases>
  % #2 - <append cases>
  % #3 - <m in amount of modulo-cases>
  % #4 - <Accumulated>
  % #5 - <m in amount of args still to gather>
  % #6 - <m in amount of modulo-cases - i>
  % #7 - <m in amount of i>
  \UD@CheckWhetherNull{#5}{%
    \UD@stopromannumeral#4%
  }{%
     \UD@CheckWhetherNull{#6}{\UD@Exchange{{#3}{m}}}%
                             {\UD@Exchange{{#6}{#7}}}%
     {\UD@WrapKArgsBetweenTokensLoopGatherArgs{#1}{#2}{#3}{#4}{#5}}%
  }%
}%
%===========================================================================
\newcommand\UD@WrapKArgsBetweenTokensLoopGatherArgs[8]{%
  % #1 - <prepend cases>
  % #2 - <append cases>
  % #3 - <m in amount of modulo-cases>
  % #4 - <Accumulated>
  % #5 - <m in amount of args still to gather>
  % #6 - <m in amount of modulo-cases - i>
  % #7 - <m in amount of i>
  % #8 - <Gathered Arg>
  \UD@PassFirstToSecond{#7m}{%
    \expandafter\UD@PassFirstToSecond\expandafter{\UD@firstoftwo{}#6}{%
      \expandafter\UD@PassFirstToSecond\expandafter{\UD@firstoftwo{}#5}{%
        \expandafter\UD@PassFirstToSecond\expandafter{%
           \romannumeral%
           \expandafter\UD@Exchange\expandafter{%
             \romannumeral\UD@ExtractKthArgCheck{#7}{}{#2}%
           }{%
             \UD@Exchange{{#8}}{%
               \expandafter\UD@Exchange\expandafter{%
                 \romannumeral\UD@ExtractKthArgCheck{#7}{}{#1}%
               }{%
                 \UD@stopromannumeral#4%
               }%
             }%
           }%
        }{%
           \UD@WrapKArgsBetweenTokensLoopCheckEnd{#1}{#2}{#3}%
        }%
      }%
    }%
  }%
}%
%===========================================================================
%% End of code for \WrapKArgsBetweenTokens.
\makeatother

\begin{document}

\noindent\hrulefill

\begin{verbatim}
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\tempa
\expandafter\expandafter\expandafter{%
  \WrapKArgsBetweenTokens{17}{Error!}{{1}{2}{3}}{{A\\}{B\\}{C\\}}%
  {one}{two}{three}{four}{five}{six}{seven}{eight}{nine}{ten}{eleven}%
  {twelve}{thirteen}{fourteen}{fifteen}{sixteen}{seventeen}%
}%
\end{verbatim}

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\tempa
\expandafter\expandafter\expandafter{%
  \WrapKArgsBetweenTokens{17}{Error!}{{1}{2}{3}}{{A\\}{B\\}{C\\}}%
  {one}{two}{three}{four}{five}{six}{seven}{eight}{nine}{ten}{eleven}%
  {twelve}{thirteen}{fourteen}{fifteen}{sixteen}{seventeen}%
}%
\PRINTtempa

\noindent\hrulefill

\begin{verbatim}
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\tempa
\expandafter\expandafter\expandafter{%
  \WrapKArgsBetweenTokens{17}{Error!}{}{}%
  {one}{two}{three}{four}{five}{six}{seven}{eight}{nine}{ten}{eleven}%
  {twelve}{thirteen}{fourteen}{fifteen}{sixteen}{seventeen}%
}%
\end{verbatim}

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\tempa
\expandafter\expandafter\expandafter{%
  \WrapKArgsBetweenTokens{17}{Error!}{}{}%
  {one}{two}{three}{four}{five}{six}{seven}{eight}{nine}{ten}{eleven}%
  {twelve}{thirteen}{fourteen}{fifteen}{sixteen}{seventeen}%
}%
\PRINTtempa

\noindent\hrulefill

\begin{verbatim}
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\tempa
\expandafter\expandafter\expandafter{%
  \WrapKArgsBetweenTokens{17}{Error!}{{1}{2}}{{A\\}{B\\}{C\\}}%
  {one}{two}{three}{four}{five}{six}{seven}{eight}{nine}{ten}{eleven}%
  {twelve}{thirteen}{fourteen}{fifteen}{sixteen}{seventeen}%
}%
\end{verbatim}

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\tempa
\expandafter\expandafter\expandafter{%
  \WrapKArgsBetweenTokens{17}{Error!}{{1}{2}}{{A\\}{B\\}{C\\}}%
  {one}{two}{three}{four}{five}{six}{seven}{eight}{nine}{ten}{eleven}%
  {twelve}{thirteen}{fourteen}{fifteen}{sixteen}{seventeen}%
}%
\PRINTtempa

\noindent\hrulefill

\begin{verbatim}
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\tempa
\expandafter\expandafter\expandafter{%
  \WrapKArgsBetweenTokens{17}{Error!}{{1}}{{A\\}}%
  {one}{two}{three}{four}{five}{six}{seven}{eight}{nine}{ten}{eleven}%
  {twelve}{thirteen}{fourteen}{fifteen}{sixteen}{seventeen}%
}%
\end{verbatim}

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\tempa
\expandafter\expandafter\expandafter{%
  \WrapKArgsBetweenTokens{17}{Error!}{{1}}{{A\\}}%
  {one}{two}{three}{four}{five}{six}{seven}{eight}{nine}{ten}{eleven}%
  {twelve}{thirteen}{fourteen}{fifteen}{sixteen}{seventeen}%
}%
\PRINTtempa

\noindent\hrulefill

\begin{verbatim}
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\tempa
\expandafter\expandafter\expandafter{%
  \WrapKArgsBetweenTokens{17}{Error!}{{\macroA}{\macroB}{\macroC}}{{&}{&}{\\}}%
  {one}{two}{three}{four}{five}{six}{seven}{eight}{nine}{ten}{eleven}%
  {twelve}{thirteen}{fourteen}{fifteen}{sixteen}{seventeen}%
}%
\end{verbatim}

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\tempa
\expandafter\expandafter\expandafter{%
  \WrapKArgsBetweenTokens{17}{Error!}{{\macroA}{\macroB}{\macroC}}{{&}{&}{\\}}%
  {one}{two}{three}{four}{five}{six}{seven}{eight}{nine}{ten}{eleven}%
  {twelve}{thirteen}{fourteen}{fifteen}{sixteen}{seventeen}%
}%
\PRINTtempa

\end{document}

在此处输入图片描述

相关内容