使用 etoolbox 自动生成表格

使用 etoolbox 自动生成表格

我有一个特殊问题,我想用 来解决etoolbox,但我不知道该怎么做。我想做的是根据上一个表中的信息自动生成一个表。最好用一个例子来解释:

\newcounter{numc}
\setcounter{numc}{0}
\newcolumntype{n}{>{\thenumc.}r<{\addtocounter{numc}{1}}}
% This is simply a column displaying the row number.

\newrobustcmd{\push}[1]{\listadd{\numcount}{\thenumc} \listadd{\ncom}{#1}}
% This command may have to be defined differently, depending on the missing code below.

\begin{xtabular}{ n l l }
  & row1,col2    & row1,col3 \\
  & row2,col2    & row2,col3 \\ \push{Comment for row 2.}
  & row3,col2    & row3,col3 \\ 
  & row4,col2    & row4,col3 \\ \push{Comment for row 4.}
  & row5,col2    & row5,col3 \\ \push{Comment for row 5.}
\end{xtabular}

\begin{xtabular}{ r l }
% The code for auto-generating the second table goes here.
% The first column is supposed to be the values in the numcount list, minus 1.
% The second column is supposed to be the text in the ncom list.
\end{xtabular}

因此输出结果应如下:

表格1:

1.   row1,col2   row1,col3
2.   row2,col2   row2,col3
3.   row3,col2   row3,col3
4.   row4,col2   row4,col3
5.   row5,col2   row5,col3

表 2:

2.   Comment for row 2.
4.   Comment for row 4.
5.   Comment for row 5.

但是,我找不到第二个表中缺失代码的好解决方案。代码应该从第一个列表生成第一列(numcount),从第二个列表生成第二列(ncom)。

您对于我如何解决这个问题有什么建议吗?

答案1

正如已经评论的那样,由于环境是局部范围,所以列表仅在表内定义,因此\listadd不起作用。因此,我们需要全局版本。tabular\listgadd然后你将其添加\thenumc到列表中,但\thenumc直到使用列表本身时才会展开,这就是我们\listxadd在这里使用 ned 的原因(\listeadd不是全局的)。
(这同样适用于\appto我实际使用的宏。)

我没有使用etoolbox' 列表,而是使用原始宏。此外,我只定义了一个宏,其中实际内容由 分隔/,我只需要循环现在列出。

该计数器intXI用于检测宏\push的第一行和最后一行\mytable

我还在宏\push之前推送了该命令\\,因为

  • 没有混淆\thenumc\push宏落在n下一行的列中)
  • 表格末尾没有空行。

迷你解决方案

在这个简单的例子中,我们可以使用

\ifnum\value{intXI}=1\relax%
  \xappto\mytable{\thenumc & #1}%
\else%
  \xappto\mytable{\noexpand\\\thenumc & #1}%
\fi%

\push宏中无需使用循环。

代码

\documentclass{article}
\usepackage{etoolbox}
\usepackage{array}
\usepackage{pgffor}

\newcounter{numc}\newcounter{intXI}
\newcolumntype{n}{>{\stepcounter{numc}\thenumc.}r}

\newrobustcmd{\push}[1]{%
    \stepcounter{intXI}%
    \ifnum\value{intXI}=1\relax%
      \xappto\mylist{\thenumc/{#1}}%
    \else%
      \xappto\mylist{,\thenumc/{#1}}%
    \fi%
}

\begin{document}
\begin{tabular}{ n l l }
  & row1,col2    & row1,col3 \\
  & row2,col2    & row2,col3 \push{Comment for row 2.} \\
  & row3,col2    & row3,col3 \\
  & row4,col2    & row4,col3 \push{Comment for row 4.} \\
  & row5,col2    & row5,col3 \push{Comment for row 5.} \\
\end{tabular}
\foreach \contentn/\contentt in \mylist {%
    \addtocounter{intXI}{-1}%
    \ifnum0=\value{intXI}\relax
      \xappto\mytable{%
          \contentn & \contentt%
      }%
    \else
      \xappto\mytable{%
          \contentn & \contentt\noexpand\\%
      }%
    \fi%
}%

\begin{tabular}{ r l }
    \mytable
\end{tabular}
\end{document}

输出

在此处输入图片描述

答案2

etoolbox如果您对不使用但使用 LaTeX3 环境的替代解决方案感兴趣xparse,请参阅这里:

\documentclass{article}
\usepackage{array,xparse}
\newcounter{numc}

\newcolumntype{n}{>{\stepcounter{numc}\thenumc.}r}

\ExplSyntaxOn
\NewDocumentEnvironment{xtabular}{ m }
 {
  \seq_gclear:N \g_eiterorm_pushes_seq
  \setcounter{numc}{0}
  \begin{tabular}{n #1}
 }
 {
  \end{tabular}
 }

\NewDocumentCommand{\push}{ m }
 {
  \eiterorm_push:n { #1 }
 }

\NewDocumentCommand{\printcomments} { }
 {
  \begin{tabular}{rl}
  \seq_use:Nnnn \g_eiterorm_pushes_seq { \\ } { \\ } { \\ }
  \end{tabular}
 }
\seq_new:N \g_eiterorm_pushes_seq
\cs_new_protected:Npn \eiterorm_push:n #1
 {
  \seq_gput_right:Nx \g_eiterorm_pushes_seq { \thenumc. \exp_not:n { & #1 } }
 }
\ExplSyntaxOff

\begin{document}

\begin{xtabular}{ l l }
  & row1,col2    & row1,col3 \\
  & row2,col2    & row2,col3 \push{Comment for row 2.} \\
  & row3,col2    & row3,col3 \\ 
  & row4,col2    & row4,col3 \push{Comment for row 4.} \\
  & row5,col2    & row5,col3 \push{Comment for row 5.} 
\end{xtabular}

\bigskip

\printcomments

\end{document}

注意\push应该去终端,\\因为否则最后一行将启动一个新行,该行将具有初始编号和空内容,并且final\\应该出现。

这个想法是\push添加到稍后被使用的序列中\printcomments

在此处输入图片描述

相关内容