在宏中使用 def 在表中写入一行时出错

在宏中使用 def 在表中写入一行时出错

对于以下 MWE

\documentclass{article}

\newcommand{\cmd}[5]{%
  \def\tA{#1}%
  \def\tB{#2}%
  \def\tC{#3}%
  \def\tD{#4}%
  \def\tE{#5}%

  \tA & \tB & \tC & \tD & \tE \\
}

\begin{document}
\begin{tabular}{ccccc}
  \cmd{1}{2}{3}{4}{5}
\end{tabular}
\end{document}

我不断收到以下错误:

! Undefined control sequence.
\cmd ...}\def \tD {#4}\def \tE {#5}\par \tA & \tB 
                                                  & \tC & \tD & \tE \\ 
l.15   \cmd{1}{2}{3}{4}{5}

为什么它不起作用?

PS. 之所以使用,\def是因为在我的文档中,我需要处理超过 9 个命令参数,因此应用此方法

答案1

表单组中的单元格tabular,因此在您的示例中,从第二个单元格开始,由 定义的命令\cmd不可用。解决方案:在 的定义中使用\gdef而不是。\def\cmd

\documentclass{article}

\newcommand{\cmd}[5]{%
  \gdef\tA{#1}%
  \gdef\tB{#2}%
  \gdef\tC{#3}%
  \gdef\tD{#4}%
  \gdef\tE{#5}%

  \tA & \tB & \tC & \tD & \tE \\
}

\begin{document}
\begin{tabular}{ccccc}
  \cmd{1}{2}{3}{4}{5}
\end{tabular}
\end{document}

答案2

您可以避免使用许多参数。下面是您的实现,\cmd您可以将参数指定为逗号分隔的列表;\selectorder您可以决定在输出中使用的顺序。

请注意,\cmd将乐意接受任何列表中的项目数;您只需指定正确的列数tabular并在其前面加上适当的\selectorder命令即可。我用两个分别有四列和五列的表格演示了这一点。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\cmd}{m}
 {
  \gablin_cmd:n { #1 }
 }

\NewDocumentCommand{\selectorder}{m}
 {
  \seq_gset_split:Nnn \g_gablin_order_seq { , } { #1 }
 }

\prop_new:N \l_gablin_arg_prop
\seq_new:N \l_gablin_output_seq
\seq_new:N \g_gablin_order_seq
\int_new:N \l_gablin_input_int

\cs_new_protected:Npn \gablin_cmd:n #1
 {
  % clear the variables' contents (it isn't really necessary)
  \prop_clear:N \l_gablin_arg_prop
  \seq_clear:N \l_gablin_output_seq
  \int_zero:N \l_gablin_input_int
  % map through the items in the argument
  \clist_map_inline:nn { #1 }
   {
    % the integer variable is used to number the items
    \int_incr:N \l_gablin_input_int
    % items are stored in a property list
    \prop_put:Nfn \l_gablin_arg_prop { \int_to_arabic:n { \l_gablin_input_int } } { ##1 }
   }
  % map through the items stating the order of items in columns
  \seq_map_inline:Nn \g_gablin_order_seq
   {
    % put the items in a new sequence
    \seq_put_right:Nx \l_gablin_output_seq
     {
      \prop_get:Nn \l_gablin_arg_prop { ##1 }
     }
   }
  % use the sequence, separating arguments with &
  \seq_use:Nn \l_gablin_output_seq { & }
 }

% we need a variant of \prop_put:Nnn store a number in the key
\cs_generate_variant:Nn \prop_put:Nnn { Nf }

\ExplSyntaxOff

\begin{document}

\selectorder{1,2,3,4}

\begin{tabular}{*{4}{c}}
\cmd{aa,ab,ac,ad} \\
\cmd{ba,bb,bc,bd} \\
\cmd{ca,cb,cc,cd} \\
\end{tabular}

\bigskip

\selectorder{5,4,3,2,1}

\begin{tabular}{*{5}{c}}
\cmd{aa,ab,ac,ad,ae} \\
\cmd{ba,bb,bc,bd,be} \\
\cmd{ca,cb,cc,cd,ce} \\
\end{tabular}

\end{document}

定义的设置\selectorder将一直有效,直到被另一个选择取消,并且是全局的,因此是否在环境中发布并不重要table。所以这个代码非常灵活。

在此处输入图片描述

相关内容