我想创建具有如下功能的新命令(伪代码):
\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}