构建表时,如何在 foreach 或条件(或其他组/环境)中使用与号 (&)?

构建表时,如何在 foreach 或条件(或其他组/环境)中使用与号 (&)?

我正在尝试构建一个表格,并且在 tabularx 环境中我想要一个循环,类似于(这里是一个 MWE):

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\newcommand{\nRows}{5}
\begin{document}


\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}}
    \foreach \r in {1,...,\nRows}{  % https://stackoverflow.com/questions/2561791/iteration-in-latex
        \textbf{column1} & two & three & four & five 
    }
\end{tabularx}

\end{document}

这不起作用,因为 & 符号会造成问题。如果我转义 &s,则整行将与文字 & 符号一起打印在第一列中,类似于:

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\newcommand{\nRows}{5}
\begin{document}


\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}}
    \foreach \r in {1,...,\nRows}{  % https://stackoverflow.com/questions/2561791/iteration-in-latex
        \textbf{column1} \& two \& three \& four \& five 
    }
\end{tabularx}

\end{document}

得出:

|column1 &      | | | |
| two & three & | | | |
| four & five   | | | |

而我想要的是:

|column 1 | two | three | four | five |
|column 1 | two | three | four | five |
|column 1 | two | three | four | five |

....

关于如何实现这一点,您有什么想法吗?我实际上并不想制作相同的行 - 行会有所不同。这只是一个 MWE。谢谢!

编辑:我尝试按照评论部分的建议实施 Herbert 的答案。结果没有输出 - 只是一个空白的 PDF。以下是我实施它的方法:

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\newcommand{\nRows}{5}

\makeatletter
\newtoks\@tabtoks
\newcommand\addtabtoks[1]{\@tabtoks\expandafter{\the\@tabtoks#1}}
\newcommand*\resettabtoks{\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother

\begin{document}

    \resettabtoks
    \foreach \r in {1,...,\nRows}{  % https://stackoverflow.com/questions/2561791/iteration-in-latex
        % \textbf{column1} \& two \& three \& four \& five 
        \addtabtoks{\textbf{column1} & two & three & four & five \\\hline}%
    }

\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}}
\printtabtoks
\end{tabularx}

\end{document}

知道我做错了什么吗?谢谢!

答案1

假设您这样做是因为您希望表的行依赖于循环中的计数器。在这种情况下,您需要一种方法来将扩展的对象添加到标记列表中。在这里,\eaddtabtoks除了 egreg 对全局分配的更正之外,我还添加了一个宏。

示例输出

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx,etoolbox}
\usepackage{tikz}
\newcommand{\nRows}{5}

\makeatletter
\newtoks\@tabtoks
\newcommand\addtabtoks[1]{\global\@tabtoks\expandafter{\the\@tabtoks#1}}
\newcommand\eaddtabtoks[1]{\edef\mytmp{#1}\expandafter\addtabtoks\expandafter{\mytmp}}
\newcommand*\resettabtoks{\global\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother

\begin{document}

\resettabtoks
\foreach \r in {1,...,\nRows}{
  \addtabtoks{\textbf{column 1} &}
  \eaddtabtoks{row \r}
  \addtabtoks{ & three & four & five \\}%
}

\begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash}p{2.2cm}*{4}{@{}>{\raggedright\arraybackslash}X}@{}}
\printtabtoks
\end{tabularx}%

\end{document}

答案2

\foreach您忽略了执行组中每个循环的事实,因此当完成它时,更改将\@tabtoks被撤消。

\global在相关位置添加(也包括\arraybackslash在最后一列的规范中,但这是另一个问题)。

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\newcommand{\nRows}{5}

\makeatletter
\newtoks\@tabtoks
%%% assignments to \@tabtoks must be global, because they are done in \foreach
\newcommand\addtabtoks[1]{\global\@tabtoks\expandafter{\the\@tabtoks#1}}
%%% variable should always be operated on always locally or always globally
\newcommand*\resettabtoks{\global\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother

\begin{document}
\resettabtoks
\foreach \r in {1,...,\nRows}{
  \addtabtoks{\textbf{column1} & two & three & four & five \\\hline}%
}
\noindent\begin{tabularx}{\textwidth}{
  @{}>{\raggedright}p{2.2cm}
  @{}>{\raggedright}X
  @{}>{\raggedright}X
  @{}>{\raggedright}X
  @{}>{\raggedright\arraybackslash}X
  @{}
}
\printtabtoks
\end{tabularx}

\end{document}

一个更复杂的例子

假设我们希望每个表行都依赖于循环索引;那么必须进行一些更改。新\addtabtoks宏采用一个可选参数,如果表达,则应为表示循环中索引的命令\foreach;在这种情况下,强制参数应为一个参数宏,如下面的代码所示;该参数应为循环索引。

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\newcommand{\nRows}{5}

\makeatletter
\newtoks\@tabtoks
%%% assignments to \@tabtoks must be global, because they are done in \foreach
\newcommand\addtabtoks[2][]{%
  \if\relax\detokenize{#1}\relax
    % no index, just append the second argument
    \global\@tabtoks\expandafter{\the\@tabtoks#2}%
  \else
    % we assume the second argument is a one parameter macro
    \global\@tabtoks\expandafter{\the\expandafter\@tabtoks\expandafter#2\expandafter{#1}}%
  \fi
}
%%% variable should always be operated on always locally or always globally
\newcommand*\resettabtoks{\global\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother

% define a one parameter macro for making the row depending on the current index
\newcommand{\tablerow}[1]{%
  \textbf{Row #1} & two & three & four & five \\\hline
}


\begin{document}
\resettabtoks
\foreach \r in {1,...,\nRows}{%
  \addtabtoks{\textbf{column1} & two & three & four & five \\\hline}%
}
\noindent\begin{tabularx}{\textwidth}{
  @{}>{\raggedright}p{2.2cm}
  @{}>{\raggedright}X
  @{}>{\raggedright}X
  @{}>{\raggedright}X
  @{}>{\raggedright\arraybackslash}X
  @{}
}
\hline
\printtabtoks
\end{tabularx}

\bigskip

\resettabtoks
\foreach \r in {1,...,\nRows}{%
  \addtabtoks[\r]{\tablerow}%
}
\noindent\begin{tabularx}{\textwidth}{
  @{}>{\raggedright}p{2.2cm}
  @{}>{\raggedright}X
  @{}>{\raggedright}X
  @{}>{\raggedright}X
  @{}>{\raggedright\arraybackslash}X
  @{}
}
\hline
\printtabtoks
\end{tabularx}

\end{document}

在此处输入图片描述

答案3

如果你愿意在这里使用另一个循环,\foreach那么还有以下选项,例如\xintFor从包中新工具。语法有点不同,并且\xintFor在此处使用并不排除\foreach在其他地方使用……

更新为热爱前沿技术的人们添加了第二种方法。

tabularx 循环

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\usepackage{xinttools}
\newcommand{\nRows}{5}
% \usepackage{tabu} % alternative to tabularx
\begin{document}

\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright\arraybackslash}X@{}}
    \xintFor* #1 in {\xintSeq {1}{\nRows}}
    \do
    {(\textsl{row #1}) \textbf{column1} & two & three & four & five
    \\ }
\end{tabularx}


% Note with a tabu environment of package tabu, \arraybackslash is not needed
% \begin{tabu} to \textwidth{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}}
%     \xintFor* #1 in {\xintSeq {1}{\nRows}}
%     \do
%     {(\textsl{row #1}) \textbf{column1} & two & three & four & five
%     \\ }
% \end{tabu}

\end{document}

这是一种依赖于可扩展循环的特殊方法(\xintFor尽管它享有表格功能,但不可扩展),并且没有计数器!(\xintFor也不使用计数器)。\xintiloopindex不能在括号内;并且在这个例子中,我们需要隐藏制表符,以使\xintiloopindex机制正常工作,因为之前遇到了不可扩展的材料。

\documentclass[10pt,a4paper]{article}
\usepackage{tabularx}
\usepackage{tikz}
\usepackage{xinttools}
\newcommand{\nRows}{5}
\def\TAB{&}
\begin{document}

\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright\arraybackslash}X@{}}
    \xintiloop [1+1]
    (\bgroup\slshape row \xintiloopindex\egroup )% \xintiloopindex can not be
                                % within braces...
            \textbf{column1} \TAB two \TAB three \TAB four \TAB five \\
    \ifnum\nRows>\xintiloopindex\space
    \repeat
\end{tabularx}

\end{document}

相关内容