我想要一个可以创建特定类型的表的宏,该表专门用于多项选择题。
所需命令\createtable{#1}{#2}{#3}
有三个参数:
- 总问题数
- 每行的列数
- 表格标题
它还应该为该表创建一个标签。
以下给出示例:
\documentclass{article}
\usepackage[table,xcdraw]{xcolor}
\usepackage{tabu}
\begin{document}
\section{createtable[20][10][table 1 caption]}
\begin{table}[h]
\centering
\caption{table 1 caption}
\label{table:1} %%% automatically generate {table:\tableCounter} as label
\begin{tabu} to 0.8\textwidth {| *{10}{X[c]|}}
\hline
\rowcolor[HTML]{EFEFEF}
1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 \\ \hline
& & & & & & & & & \\ [1ex]\hline
\rowcolor[HTML]{EFEFEF}
11 & 12 & 13 & 14 & 15 & 16 & 17 & 18 & 19 & 20 \\ \hline
& & & & & & & & & \\ [1ex]\hline
\end{tabu}
\end{table}
\section{createtable[17][10][table 2 caption]}
\begin{table}[h]
\centering
\caption{table 2 caption}
\label{table:2} %%% automatically generate {table:\tableCounter} as label
\begin{tabu} to 0.8\textwidth {| *{10}{X[c]|}}
\hline
\rowcolor[HTML]{EFEFEF}
1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 \\ \hline
& & & & & & & & & \\ [1ex]\hline
\rowcolor[HTML]{EFEFEF}
11 & 12 & 13 & 14 & 15 & 16 & 17 & & & \\ \hline
& & & & & & & \cellcolor[HTML]{9B9B9B} & \cellcolor[HTML]{9B9B9B} & \cellcolor[HTML]{9B9B9B} \\ [1ex]\hline
\end{tabu}
\end{table}
\section{createtable[17][6][table 3 caption]}
\begin{table}[h]
\centering
\caption{table 3 caption}
\label{table:3} %%% automatically generate {table:\tableCounter} as label
\begin{tabu} to 0.8\textwidth {| *{6}{X[c]|}}
\hline
\rowcolor[HTML]{EFEFEF}
1 & 2 & 3 & 4 & 5 & 6 \\ \hline
& & & & & \\ [1ex]\hline
\rowcolor[HTML]{EFEFEF}
7 & 8 & 9 & 10 & 11 & 12 \\ \hline
& & & & & \\ [1ex]\hline
\rowcolor[HTML]{EFEFEF}
13 & 14 & 15 & 16 & 17 & \\ \hline
& & & & & \cellcolor[HTML]{9B9B9B} \\ [1ex]\hline
\end{tabu}
\end{table}
\end{document}
我怎样才能做到这一点?
答案1
使用强大的tikz
包,我们可以定义一个\newcommand
具有三个参数的包,如下所示:
\createtable{<# Questions>}{<# Columns>}{<Table caption>}
像这样:
\documentclass[12pt,a4paper]{article}
\usepackage{tikz,xcolor}
\usetikzlibrary{calc}
\begin{document}
\newcounter{xy}
\definecolor{Qcolor}{HTML}{EFEFEF}
\definecolor{noQcolor}{HTML}{9B9B9B}
\newcommand{\createtable}[3]{%
\begin{table}[!h]\centering
\pgfmathparse{ceil(#1/#2)}
\edef\yfin{\pgfmathresult}
\setcounter{xy}{0}
\begin{tikzpicture}[cell/.style={draw,minimum size=1cm}]
\foreach \y [count=\yi] in {1,...,\yfin}{%
\foreach \x [count=\xi] in {1,...,#2}{%
\addtocounter{xy}{1}
\node [cell,fill=Qcolor]at ([shift={(0,-\yi)}]\xi,-\yi) {%
\ifnum\the\value{xy}>#1{}\else\the\value{xy}\fi};
\node [cell,fill={\ifnum\the\value{xy}>#1noQcolor\else white\fi}]
at ([shift={(0,-\yi-1)}]\xi,-\yi) {};}}
\end{tikzpicture}
\caption{#3} \label{Tab:#1#2}
\end{table}
}
\createtable{20}{10}{Table 1 caption}
\createtable{17}{10}{Table 2 caption}
\createtable{17}{6}{Table 3 caption}
We can refer to Table \ref{Tab:2010}, Table \ref{Tab:1710} or Table \ref{Tab:176} as usual.
\end{document}
如果要求表格占据总计\linewidth
,我们可以修改单元格的宽度使其等于,\linewidth/# columns
如下所示:
\newcounter{xy}
\definecolor{Qcolor}{HTML}{EFEFEF}
\definecolor{noQcolor}{HTML}{9B9B9B}
\newcommand{\createtable}[3]{%
\begin{table}[!h]\centering
\pgfmathparse{ceil(#1/#2)}
\edef\yfin{\pgfmathresult}
\setcounter{xy}{0}
\begin{tikzpicture}[cell/.style={draw,minimum height=1cm,minimum width=\linewidth/#2}]
\foreach \y [count=\yi] in {1,...,\yfin}{%
\foreach \x [count=\xi] in {1,...,#2}{%
\addtocounter{xy}{1}
\node [cell,fill=Qcolor]at ([shift={(0,-\yi)}]\xi*\linewidth/#2,-\yi) {%
\ifnum\the\value{xy}>#1{}\else\the\value{xy}\fi};
\node [cell,fill={\ifnum\the\value{xy}>#1noQcolor\else white\fi}]
at ([shift={(0,-\yi-1)}]\xi*\linewidth/#2,-\yi) {};}}
\end{tikzpicture}
\caption{#3} \label{Tab:#1#2}
\end{table}
}
细节
PGF 有一个很好的数学引擎,除了用于重复操作的 for/foreach 循环外,我们还可以用它来评估许多表达式并执行许多数学函数。由于所需的表格主要是有序排列的问题编号及其下方的空单元格,因此使用 for 循环是一种自然选择。此外,在 TiKZ 中用某种颜色填充节点非常容易。
我过去常常\pgfmathparse{<expression>}
将行数计算为,\pgfmathparse{ceil(#questions/#columns)}
并将其存储在行\yfin
的迭代中。计数器xy
用于保存\newcounter{xy}
初始化为零的问题号\setcounter{xy}{0}
,并在每次迭代中更新\addtocounter{xy}{1}
。xcolor
包用于着色。条件xy
用于着色颜色,就好像fill={\ifnum\the\value{xy}>#1noQcolor\else white\fi}
没有问题一样。为了引用表格,\label{Tab:#1#2}
用作每个表格的唯一标签。
代码还有很大的改进空间,但这至少满足了 OP 的要求。