我正在尝试创建一个名为 FlexibleTable 的自定义 LaTeX 环境,它允许我灵活地输入表格单元格。该表格设计为四列。我想要一个命令来输入下一个单元格或两个单元格,并在必要时转到下一行。例如,第一个、第二个、第三个、第四个单元格转到第一行,但第五个单元格将向表格中添加一行

这是我的代码:

\documentclass[a4paper,10pt]{article}
\usepackage{environ}

% Define the table column width
\newlength{\TableColWidth}
\setlength{\TableColWidth}{4.9cm}

% Initialize the counter for columns
\newcounter{flexcol}
\setcounter{flexcol}{0}

% Define the FlexibleTable environment
\NewEnviron{FlexibleTable}{%
    \setcounter{flexcol}{0}%
    \begin{tabular}{| p{\TableColWidth} | p{\TableColWidth} | p{\TableColWidth} | p{\TableColWidth} |}
    \hline
    \BODY
    \ifnum\value{flexcol}>0
        % Calculate the number of empty cells needed to complete the row
        \multicolumn{\the\numexpr4-\value{flexcol}\relax}{c|}{} \\ \hline
    \fi
    \end{tabular}
}

% Define the FlexCell command using \newcommand
\newcommand{\FlexCell}[1]{%
    #1%
    \stepcounter{flexcol}%
    \ifnum\value{flexcol}=4
        \\ \hline
        \setcounter{flexcol}{0}%
    \else
        &%
    \fi
}

\begin{document}

\begin{FlexibleTable}
    \FlexCell{\textbf{Header 1}}
    \FlexCell{\textbf{Header 2}}
    \FlexCell{\textbf{Header 3}}
    \FlexCell{\textbf{Header 4}}
    
    \FlexCell{Row 1, Cell 1}
    \FlexCell{Row 1, Cell 2}
    \FlexCell{Row 1, Cell 3}
    \FlexCell{Row 1, Cell 4}
    
    \FlexCell{Row 2, Cell 1} % This will create an incomplete row
\end{FlexibleTable}

\end{document}

我收到以下错误:

! Incomplete \ifnum; all text was ignored after line 51.
<inserted text> 
                \fi 
l.51 \end{FlexibleTable}

有人能指导我如何解决这个问题吗?

1


  • – 


最佳答案
2

使用expl3。我们定义\FlexCell只是将一个项目添加到序列中。完成后,序列将使用空单元格进行扩展,以获得 4 的倍数。

最后映射序列:交付项目,并且如果索引是 4 的倍数,我们还会发出\\ \hline,否则&

\documentclass[a4paper,10pt]{article}

\ExplSyntaxOn

% Define the FlexibleTable environment
\NewDocumentEnvironment{FlexibleTable}{m+b}
 {
  \zakirov_flextab:nn {#1} {#2}
 }{}

% Define the FlexCell command
\NewDocumentCommand{\FlexCell}{m}
 {
  \seq_put_right:Nn \l_zakirov_flextab_seq {#1}
 }

\seq_new:N \l_zakirov_flextab_seq

% the main function
\cs_new_protected:Nn \zakirov_flextab:nn
 {
  % start the tabular
  \begin{tabular}{ | *{4}{p{#1}|} }
  \hline
  % populate the sequence
  #2
  % ensure that the number of cells is a multiple of 4
  \int_compare:nF { \int_mod:nn {\seq_count:N \l_zakirov_flextab_seq} {4} == 0 }
   {% we need to add some dummy cells
    \prg_replicate:nn { 4 - \int_mod:nn {\seq_count:N \l_zakirov_flextab_seq} {4} }
     {
      \seq_put_right:Nn \l_zakirov_flextab_seq {}
     }
   }
  % deliver the contents: at multiples of 4 issue '\\ \hline', else `&'
  \seq_map_indexed_function:NN \l_zakirov_flextab_seq \__zakirov_flextab_cell:nn
  % end
  \end{tabular}
}

% the auxiliary command
\cs_new_protected:Nn \__zakirov_flextab_cell:nn
 {% #1 = current index, #2 = item
  #2 \int_compare:nTF { \int_mod:nn {#1}{4} == 0 } { \\ \hline } { & }
 }

\ExplSyntaxOn

\begin{document}

\begin{FlexibleTable}{2.5cm}
    \FlexCell{\textbf{Header 1}}
    \FlexCell{\textbf{Header 2}}
    \FlexCell{\textbf{Header 3}}
    \FlexCell{\textbf{Header 4}}
    
    \FlexCell{Row 1, Cell 1}
    \FlexCell{Row 1, Cell 2}
    \FlexCell{Row 1, Cell 3}
    \FlexCell{Row 1, Cell 4}
    
    \FlexCell{Row 2, Cell 1} % This will create an incomplete row
\end{FlexibleTable}

\end{document}

通常(或至少经常)这种布局最好被视为一段流动的框而不是表格结构。

\documentclass[a4paper,10pt]{article}

\NewDocumentEnvironment{FlexibleTable}{}{\begin{flushleft}}{\end{flushleft}}

% Define the FlexCell command using \newcommand
\newcommand{\FlexCell}[1]{\hfil\makebox[.24\textwidth][l]{#1}\hfil}


\begin{document}

\begin{FlexibleTable}
    \FlexCell{\textbf{Header 1}}
    \FlexCell{\textbf{Header 2}}
    \FlexCell{\textbf{Header 3}}
    \FlexCell{\textbf{Header 4}}    
    \FlexCell{Row 1, Cell 1}
    \FlexCell{Row 1, Cell 2}
    \FlexCell{Row 1, Cell 3}
    \FlexCell{Row 1, Cell 4}   
    \FlexCell{Row 2, Cell 1} % This will create an incomplete row
\end{FlexibleTable}

\end{document}

1

  • 非常感谢。我喜欢它——简洁明了。但需要一张桌子 🙁


    –