使用 hspace 创建动态表

使用 hspace 创建动态表

我正在尝试创建一个具有动态列数的动态表,并且hspace

以下是我目前所掌握的信息:

\documentclass{article}
\usepackage{tabularx}
\usepackage{array}
\usepackage{forloop}

\begin{document}
    \edef\rowdescriptor{|c|}
    \edef\pointsdescriptor{}
    \newcounter{tempcounter}
    \forloop{tempcounter}{0}{\value{tempcounter} < 5}{
        \edef\rowdescriptor{\rowdescriptor c|}
        \edef\pointsdescriptor{\expandafter\noexpand\pointsdescriptor & }
    }

    \expandafter\tabular\expandafter{\rowdescriptor}
    \hline
    \pointsdescriptor \\
    \hline
    \endtabular
\end{document}

这会产生六个框,正如预期的那样。但是,我想让框更宽,同时保留 ,c因为实际表格有更多行,其中的文本需要居中。为此,我使用了\hspace。因此,当我将 for 循环中的第二行更改为

\edef\pointsdescriptor{\expandafter\noexpand\pointsdescriptor & \noexpand{\hspace{0.75cm}}}

我立即收到错误“ \forloop 的使用与其定义不匹配”。

我是否以某种方式错误地扩展了令牌? 这里有什么错误? 我该如何做得更好?

答案1

forloop包似乎很旧了...我建议\foreach使用前列腺素. 对于递归构建命令,我总是使用\gappto使用电子工具箱包。另外,您不需要构建宏,\rowdescriptor因为您可以定义:

\def\rowdescriptor{*5{|c}|}

意思*5{|c}是“重复列规范|c5 次”。

综合起来,下面就可以实现您想要的效果:

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

\begin{document}
    \def\rowdescriptor{*5{|c}|}
    \foreach \x in {1,...,4}{
        \gappto\pointsdescriptor{\hspace*{0.75cm}&}
    }
    \xappto\pointsdescriptor{\noexpand\hspace*{0.75cm}}
    \expandafter\tabular\expandafter{\rowdescriptor}
    \hline
    \pointsdescriptor \\
    \hline
    \endtabular
\end{document}

我还使用了\hspace*as 来强制插入空格。请注意,循环后必须添加一个“extra”,\hspace*因为有 4 个&s 和 5 列。以下是输出:

在此处输入图片描述

编辑

这是将列数隐藏在宏中的版本。当然,你可以\csname ....\endcsname在这里使用,但我更喜欢使用\csuse{...}但我更电子工具箱 包,因为我发现这更容易阅读。

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

\begin{document}
    \def\numberofcolumns{5}
    \def\pointsdescriptor{}% initialise
    \xdef\rowdescriptor{*{\csuse{numberofcolumns}}{|c}|}
    \foreach \x in {1,...,\numexpr\csuse{numberofcolumns}-1}{
        \gappto\pointsdescriptor{\hspace*{0.75cm}&}
    }
    \xappto\pointsdescriptor{\noexpand\hspace*{0.75cm}}
    \expandafter\tabular\expandafter{\rowdescriptor}
    \hline
    \pointsdescriptor \\
    \hline
    \endtabular
\end{document}

输出与上面相同。请注意,如果{\csuse{numberofcolumns}}列数超过 9 列,则应该使用括号。此外,\xdef\rowdescriptor上面的 不是必需的,因为宏numberofcolumns是“静态的”,但\xdef如果您的实际 csname 依赖于计数器,则 是必需的。

这是第三种变体,其中代码放在一个宏中,该宏将列数作为可选参数,默认为 5:

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

\newcommand\mytabular[1][5]{%
    \bgroup%
    \def\rowdescriptor{*{#1}{|c}|}%
    \def\pointsdescriptor{}%
    \foreach \x in {1,...,\numexpr#1-1}{%
        \gappto\pointsdescriptor{\hspace*{0.75cm}&}
    }%
    \xappto\pointsdescriptor{\noexpand\hspace*{0.75cm}}%
    \expandafter\tabular\expandafter{\rowdescriptor}
    \hline
    \pointsdescriptor \\
    \hline
  \endtabular%
  \egroup%
}
\begin{document}
  \mytabular

  \mytabular[7]
\end{document}

这次的输出是:

在此处输入图片描述

我不确定您的实际应用是什么,但我可能会尝试使用类似这种方法。

答案2

您的问题是,只要有一个(第一个)标记需要保护以免扩展,就\expandafter\noexpand\pointsdescriptor可以工作。使用 e-TeX,可以使用 轻松覆盖此问题。您也不需要,因为后者适用于,而 已经不可扩展。这意味着您将得到\pointsdescriptor\unexpanded{\noexpand\hspace{0.75cm}}\noexpand{\hspace{0.75cm}}\noexpand{

\documentclass{article}
\usepackage{tabularx}
\usepackage{array}
\usepackage{forloop}

\begin{document}
    \edef\rowdescriptor{|c|}
    \edef\pointsdescriptor{}
    \newcounter{tempcounter}
    \forloop{tempcounter}{0}{\value{tempcounter} < 5}{
        \edef\rowdescriptor{\rowdescriptor c|}
        \edef\pointsdescriptor{\unexpanded\expandafter{\pointsdescriptor} & {\noexpand\hspace{0.75cm}}}
    }

    \expandafter\tabular\expandafter{\rowdescriptor}
    \hline
    \pointsdescriptor \\
    \hline
    \endtabular
\end{document}

值得注意的是,这没有放入足够的空间:安德鲁的回答已经涵盖了解决这个问题的方法(我认为这通常是一种更好的方法)。

相关内容