自动生成显示分组的表格

自动生成显示分组的表格

在我的文档中,我使用一个命令来创建编号元素,使用另一个命令将所有元素分组到下一个分组命令。我尝试创建一个显示这些分组的表格,如下例所示:

\documentclass{article}    

\usepackage{tabularx}
\newcolumntype{x}{>{\centering\arraybackslash\hspace{0pt}}p{0.9cm}}
\newcolumntype{Y}{>{\centering\arraybackslash}X}    

\newcounter{Elements}
\setcounter{Elements}{1}    

\newcommand{\newgrouping}[1]{#1 starts.\\}
\newcommand{\newelement}{Element \theElements.\\ \addtocounter{Elements}{1}}    

\begin{document}
\newgrouping{Some}
\newelement
\newelement
\newgrouping{Stuff}
\newelement
\newelement
\newelement
\newgrouping{Here}
\newelement    

First table:
\begin{tabular}{|@{}c@{}|@{}c@{}|@{}c@{}|}
\hline
\begin{tabularx}{2cm}{Y|Y} 1 & 2 \end{tabularx} & \begin{tabularx}{2cm}{Y|Y|Y} 3 & 4 & 5 \end{tabularx} & \begin{tabularx}{2cm}{Y} 6 \end{tabularx} \\
\hline
Some & Stuff & Here \\ \hline
\end{tabular}    

\vspace{3em}
Second table:
\begin{tabular}{|x|x|x|x|x|x|}
\hline
1 & 2 & 3 & 4 & 5 & 6 \\
\hline
\multicolumn{2}{|c|}{Some} & \multicolumn{3}{c|}{Stuff} & \multicolumn{1}{c|}{Here} \\ \hline
\end{tabular}    

\end{document}

您可以在这张图中看到输出: 带表格的代码输出

在上面的代码中,表格是硬编码的。我希望它们能够自动适应新的分组和元素。我更喜欢第一个表格版本,但由于我认为第二个版本更简单一些,所以我发布了构建第二个表格版本的未完成代码。

在其他一些帖子的帮助下,我走到了这一步(代码应该可以编译)。现在我无法自动创建表格的第二行:

\documentclass{article}    

\usepackage{tabularx}
\newcolumntype{x}{>{\centering\arraybackslash\hspace{0pt}}p{0.9cm}}
\makeatletter
\newcolumntype{\expand}{}
\long\@namedef{NC@rewrite@\string\expand}{\expandafter\NC@find}
\makeatother    

\newcounter{Elements}
\setcounter{Elements}{1}    

\newcounter{ElementsInGroup}
\setcounter{ElementsInGroup}{0}
\newcounter{GroupNumber}
\setcounter{GroupNumber}{0}
\newcommand{\currentgroupname}{}
\newcommand{\tablealignment}{}
\newcommand{\elementnumberrow}{}
\newcommand{\groupnamesrow}{}
\newcommand{\oldgroupnamesrow}{}
\newcommand{\currentgroupnamesrow}{}    

\newcommand{\newgrouping}[1]{#1 starts.\\
\setcounter{ElementsInGroup}{0}
\addtocounter{GroupNumber}{1}
\renewcommand{\currentgroupname}{#1}
\expandafter\edef\expandafter\oldgroupnamesrow\expandafter{\groupnamesrow}
}
\newcommand{\newelement}{Element \theElements.\\
\expandafter\edef\expandafter\elementnumberrow\expandafter{\elementnumberrow \ifnum\theElements=1{}\else&\fi \theElements}
\addtocounter{ElementsInGroup}{1}
\expandafter\edef\expandafter\currentgroupnamesrow\expandafter{\theElementsInGroup \currentgroupname} % !!
\expandafter\edef\expandafter\groupnamesrow\expandafter{\oldgroupnamesrow \ifnum\theGroupNumber=1{}\else,\fi \currentgroupnamesrow} % need to replace , with &
\expandafter\def\expandafter\tablealignment\expandafter{\tablealignment x|}
\addtocounter{Elements}{1}}    

\begin{document}
\newgrouping{Some}
\newelement
\newelement
\newgrouping{Stuff}
\newelement
\newelement
\newelement
\newgrouping{Here}
\newelement    


\groupnamesrow % prints 2Some,3Stuff,1Here    

\begin{tabular}{|\expand\tablealignment}
\hline
\elementnumberrow \\
\hline
\multicolumn{2}{|c|}{Some} & \multicolumn{3}{c|}{Stuff} & \multicolumn{1}{c|}{Here} 
\\ \hline
\end{tabular}    


\end{document}

问题是,只要我\multicolumn向行中添加!!-comment,就会收到错误“未定义的控制序列 \newelement”。当我尝试使用 tabularx 制作第一个版本的表格时,我也遇到了类似的问题。

阅读了一些帖子后,我想知道在这种情况下是否根本不可能使用多列或 tabularx,在哪里\edef需要? 如果是真的,也许还有其他方法可以实现我想要的?

答案1

按照 Christian 的建议,我使用expl3特征来解决了我的问题。我还没有找到生成第二个版本表格的方法,但由于第一个版本无论如何都是我最喜欢的,所以这不是问题。

当然,还有比我的解决方案更优雅的方法来解决这个问题。具体来说,我首先生成一个包含我想要创建的单元格的对齐和内容的字符串,然后使用expl3特征进行解析以生成具有拟合的行tabularx,这过于复杂。但是,在我的应用程序中,我还必须像这样存储数据 -使用稍后定义的宏值- 我不确定如何使用expl3序列来实现这一点。

我还发现这非常有帮助:如何结合 \seq_use:Nn 和 \seq_map_inline:Nn?但是我找不到使用来自两个序列而不是一个序列的元素来生成多列的方法,这就是为什么我无法生成表格的第二个版本的原因。

这是我的第一个版本的代码:

\documentclass{article}    

\usepackage{tabularx}
\usepackage{xparse}    

\newcolumntype{Y}{>{\centering\arraybackslash}X}    

\makeatletter
\newcolumntype{\expand}{}
\long\@namedef{NC@rewrite@\string\expand}{\expandafter\NC@find}
\makeatother    

\newcounter{Elements}
\setcounter{Elements}{1}
\newcounter{ElementsInGroup}
\setcounter{ElementsInGroup}{0}
\newcounter{GroupNumber}
\setcounter{GroupNumber}{0}
\newcommand{\currenttabularxalignment}{}
\newcommand{\currentgroupelements}{}
\newcommand{\elementrowstring}{moo} % nonsense element, to be removed later
\newcommand{\oldelementrowstring}{}
\newcommand{\groupnamesrow}{}    

\newcommand{\newgrouping}[1]{#1~starts.\\
\addtocounter{GroupNumber}{1}
\expandafter\edef\expandafter\groupnamesrow\expandafter{\groupnamesrow\ifnum\theGroupNumber=1{}\else&\fi#1}
\expandafter\edef\expandafter\oldelementrowstring\expandafter{\elementrowstring}
\renewcommand{\currentgroupelements}{}
\renewcommand{\currenttabularxalignment}{}
\setcounter{ElementsInGroup}{0}
}
\newcommand{\newelement}{Element~\theElements.\\
\expandafter\edef\expandafter\currentgroupelements\expandafter{\currentgroupelements \ifnum\theElementsInGroup=0{}\else&\fi \theElements}
\expandafter\edef\expandafter\currenttabularxalignment\expandafter{\currenttabularxalignment\ifnum\theElementsInGroup=0{}\else|\fi Y} 
\expandafter\edef\expandafter\elementrowstring\expandafter{\oldelementrowstring;\currenttabularxalignment,\currentgroupelements} 
\addtocounter{Elements}{1}
\addtocounter{ElementsInGroup}{1}}    

\begin{document}
\newgrouping{Some}
\newelement
\newelement
\newgrouping{Stuff}
\newelement
\newelement
\newelement
\newgrouping{Here}
\newelement    

% now \elementrowstring looks like
% moo;Y|Y,1&2;Y|Y|Y,3&4&5;Y,6
% and we make a table row from that    

% \renewcommand{\elementrowstring}{moo;Y|Y,1&2;Y|Y|Y,3&4&5;Y,6}    

\ExplSyntaxOn
\seq_new:N \l_nyxl_groups
\seq_new:N \l_nyxl_groupboth    

\cs_generate_variant:Nn \seq_set_split:Nnn {Nnx} % define \seq_set_split:Nnx that expands the last argument
\seq_set_split:Nnx \l_nyxl_groups { ; } {\elementrowstring}    

\cs_new:Npn \nyxl_elementgroupcell:n #1
{
    & \seq_set_split:Nnn \l_nyxl_groupboth { , } {#1} 
    \seq_get_left:NN \l_nyxl_groupboth \l_tmpa_tl 
    \seq_get_right:NN \l_nyxl_groupboth \l_tmpb_tl
    \begin{tabularx}{2cm}{\expand\l_tmpa_tl} 
    \l_tmpb_tl
    \end{tabularx}
}
\cs_new:Npn \nyxl_elementsrow:
{
  \seq_map_function:NN \l_nyxl_groups \nyxl_elementgroupcell:n
}    

\seq_pop_left:NN \l_nyxl_groups \l_tmpa_tl %pop first nonsense-element    

\begin{tabular}{|c|*{\theGroupNumber}{@{}c@{}|}}
\hline
\textit{Elements} \nyxl_elementsrow: \\
\hline
\textit{Groups} & \groupnamesrow \\
\hline
\end{tabular}    

\ExplSyntaxOff
\end{document}

产生

自动生成表格

相关内容