答案1
包environ
用于捕获环境的内容。LaTeX3 代码(包expl3
)将其拆分为行、单元格和更通用的编程工具。与其像我一样创建一个具有 4 个参数的环境,不如在定义中对其中一些参数进行硬编码(如果更实用的话)。
\documentclass{article}
\usepackage{environ}
\usepackage{expl3}
\ExplSyntaxOn
\seq_new:N \l_jb_lines_seq
\seq_new:N \l_jb_tmp_seq
\tl_new:N \l_jb_result_tl
\int_new:N \l_jb_cols_int
\int_new:N \l_jb_cell_int
\tl_new:N \l_jb_one_line_tl
\NewEnviron{mytable}[4][]
{
\seq_set_split:NnV \l_jb_lines_seq { \\ } \BODY
%
% If the user gives no indication of number of cells, find the max
% number by reading all rows. Otherwise, use the user-given value,
% all extras will be thrown out silently.
%
\tl_if_empty:nTF {#1}
{ \jb_get_max_cells:NN \l_jb_lines_seq \l_jb_cols_int }
{ \int_set:Nn \l_jb_cols_int {#1} }
%
% Build the result into a token list, initially the begin-code |#3|.
% For each line |##1|, add a call to the command |#2| with exactly
% |\l_jb_cols_int| arguments. Then append the end-code |#4|.
% Finally, use the token list.
%
\tl_set:Nn \l_jb_result_tl {#3}
\seq_map_inline:Nn \l_jb_lines_seq
{ \jb_append_one_line:NnNn \l_jb_result_tl {#2} \l_jb_cols_int {##1} }
\tl_put_right:Nn \l_jb_result_tl {#4}
\tl_use:N \l_jb_result_tl
}
\cs_new_protected:Npn \jb_get_max_cells:NN #1#2
{
% Find the max number of cells over all lines.
% Not terribly efficient way of counting |&|: split at each |&|
% and store in a tmp sequence, then count its items.
%
\int_zero:N #2
\seq_map_inline:Nn #1
{
\seq_set_split:Nnn \l_jb_tmp_seq { & } {##1}
\int_set:Nn #2
{ \int_max:nn #2 { \seq_count:N \l_jb_tmp_seq } }
}
}
\cs_new_protected:Npn \jb_append_one_line:NnNn #1#2#3#4
{
\tl_set:Nn \l_jb_one_line_tl {#2}
\seq_set_split:Nnn \l_jb_tmp_seq { & } {#4}
\int_set:Nn \l_jb_cell_int { \seq_count:N \l_jb_tmp_seq }
\int_compare:nNnTF \l_jb_cell_int > {#3}
{
\int_zero:N \l_jb_cell_int
\seq_map_inline:Nn \l_jb_tmp_seq
{
\int_compare:nNnF \l_jb_cell_int < {#3} { \seq_map_break: }
\int_incr:N \l_jb_cell_int
\tl_put_right:Nn \l_jb_one_line_tl { {##1} }
}
}
{
\seq_map_inline:Nn \l_jb_tmp_seq
{ \tl_put_right:Nn \l_jb_one_line_tl { {##1} } }
\tl_put_right:Nx \l_jb_one_line_tl
{ \prg_replicate:nn { #3 - \l_jb_cell_int } { { } } }
}
\tl_put_right:NV #1 \l_jb_one_line_tl
}
\ExplSyntaxOff
\begin{document}
\newcommand{\RowMacro}[5]{[1: #1] & [2: #2] & [3 and 4: #3, #4] & [5: #5]\\}
\begin{mytable}[5]{\RowMacro}{\begin{tabular}{cccc}}{\end{tabular}}
a & b & c \\
d & e & f & g & h & extra\notused \\
ijk & l
\end{mytable}
\end{document}
答案2
一个简单的解决方案,如果你知道列数:
\def\RowMacroIII{{#1}&{#2}&{#3}\\}
用法
\RowMacro{a}{b}{c}
和
\def\RowMacroIV{{#1}&{#2}&{#3}&{#4}\\}
用法
\RowMacro{a}{b}{c}{d}