我正在尝试编写一个问题作业,其中的文本框包含书面解决方案。文本框应均匀分布在页面上,占用所有可用空间。预期结果应如下所示:
\documentclass{scrartcl}
\begin{document}
Please justify all your answers to the following questions.
\begin{enumerate}
\item Is this = that?\hfill 2 points
\fbox{\parbox[t][5cm][t]{\dimexpr\linewidth-2\fboxrule-2\fboxsep}{%
Solution.
Bla bla bla.
}}
\item Is that = this?\hfill 2 points
\fbox{\parbox[t][5cm][t]{\dimexpr\linewidth-2\fboxrule-2\fboxsep}{%
Solution.
}}
\end{enumerate}
\end{document}
当然,我希望盒子占据所有可用空间。我该如何实现这一点?
答案1
经过思考,我发现最简单的填充方法就是使用\vfill
并让 TeX 完成工作。不幸的是,你需要用方框框住内容,而\vfill
在方框内则不起作用(特别是在 中\hbox
)。解决方案是使用 TikZ 及其remember picture
和overlay
功能首先标记开头,然后绘制框架。
请注意,您甚至可以重复使用相同的节点名称,而不需要对其进行编号,这也是可能的。
这在第二次编译运行后有效。第一次只显示错误的帧。如果您需要扩大一个问题的垂直空间,您可以\vfill
在答案文本的末尾放置另一个问题,使其大小是其他问题的两倍。
\documentclass[a4paper]{scrartcl}
\usepackage{tikz}
\newenvironment{questions}{%
\enumerate
}{%
\endenumerate
\newpage
}
\newcommand\question[3]{%
\item {#1}\hfill{#2}\par\noindent
\tikz[remember picture, overlay] \node (question start) at (-\fboxsep-\fboxrule, \ht\strutbox+\fboxsep+\fboxrule) {};
#3\vfill\par\noindent
\tikz[remember picture, overlay] \draw (\linewidth+\fboxsep+\fboxrule, 0) rectangle (question start);
}
\begin{document}
Please justify all your answers to the following questions.
\begin{questions}
\question{Is this = that?}{2 points}{%
Bla bla bla.
}
\question{Is this = this?}{2 points}{%
Bla bla bla.
}
\end{questions}
\begin{questions}
\question{Is this = that?}{2 points}{%
Bla bla bla.
}
\question{Is this = this?}{2 points}{%
Bla bla bla.
}
\question{Is this = there?}{2 points}{%
Bla bla bla.
}
\end{questions}
\end{document}
答案2
这不是一个完美的解决方案,而只是一个起点。tcolorbox
提供的选项equal height group
使多个框(经过两次编译)具有与该组中最大框(自然高度)相同的高度。 您可以使用 确保所有框都具有一定的尺寸minimum for equal height group
,因此结合这两个选项,所有框的最小尺寸都将取决于其自然高度。
我不知道每页有多少可用空间,但您可以尝试修复一个问题minimum for equal height group
,经过一些实验后可以修复。您还可以height fill
在每页的最后一个框中使用选项。此选项将确保使用所有垂直空间。
\documentclass{article}
\usepackage{lmodern}
\usepackage[most]{tcolorbox}
\tcbset{
colframe=black, colback=white, notitle, before upper={Solution:},
equal height group=A,
minimum for equal height group=A:7cm}
\begin{document}
Please justify all your answers to the following questions.
\begin{enumerate}
\item Is this = that?\hfill 2 points
\begin{tcolorbox}
\end{tcolorbox}
\item Is this = that?\hfill 2 points
\begin{tcolorbox}[height fill]
\end{tcolorbox}
\end{enumerate}
%Following line creates a new group with different size
\tcbset{equal height group=B, minimum for equal height group=B:3cm}
\begin{enumerate}
\item Is this = that?\hfill 2 points
\begin{tcolorbox}
\end{tcolorbox}
\item Is this = that?\hfill 2 points
\begin{tcolorbox}
\end{tcolorbox}
\item Is this = that?\hfill 2 points
\begin{tcolorbox}
\end{tcolorbox}
\item Is this = that?\hfill 2 points
\begin{tcolorbox}[height fill]
\end{tcolorbox}
\end{enumerate}
\end{document}
答案3
因为我对 并不完全满意tcolorbox
,所以我尝试找到自己的解决方案。以下 MWE 在两次编译后稳定下来。它将每个框的可用空间写入辅助文件并在下一轮读取它们。但是,事情很容易变得一团糟,在这种情况下,从辅助文件中删除相应的内容会有所帮助。
\documentclass[a4paper]{scrartcl}
\makeatletter
\newif\ifresetboxes
% Remaining space on the current page.
\def\restofpage{\dimexpr\pagegoal-\pagetotal-\baselineskip\relax}
% Save available space of current group to the aux file.
\newlength\restofpage@lastrun
\newcounter{vfill@write@groups}
\newcommand{\saverestofpage}{
\stepcounter{vfill@write@groups}%
% Name of the macro the rest of the page is to be saved to.
\def\length@name{restofpage@\roman{vfill@write@groups}}%
% Rest of this page from last compilation. If undefined or if reset mode,
% set this to 0pt.
\expandafter\ifcsname\length@name\endcsname
\expandafter\expandafter\expandafter\restofpage@lastrun\expandafter\expandafter\expandafter=\expandafter\csname\length@name\endcsname
\else
\setlength{\restofpage@lastrun}{0pt}
\fi%
\ifresetboxes
\setlength{\restofpage@lastrun}{0pt}
\fi
% Save new rest of page = old rest of page + current rest of page.
\immediate\write\@auxout{%
\noexpand\global\noexpand\@namedef{\length@name}{%
\the\dimexpr
\restofpage / \thevfillboxes + \restofpage@lastrun
\relax
}
}
\typeout{Total space available: \the\restofpage}
\typeout{Boxes on this page: \thevfillboxes}
\setcounter{vfillboxes}{0}
\resetboxesfalse
}
% Read available space for the next group from the aux file.
\newlength\remainingspace@perbox
\newcounter{vfill@read@groups}
\newcommand{\getrestofpage}{
% Define macros for the names values for the current page are to be read from.
\stepcounter{vfill@read@groups}
\def\length@name{restofpage@\roman{vfill@read@groups}}
% Set \remainingspace to the value of the length named by \length@name
\ifresetboxes
\setlength{\remainingspace@perbox}{0pt}
\else
\setlength{\remainingspace@perbox}{
\expandafter\ifcsname\length@name\endcsname%
\expandafter\csname\length@name\endcsname
\else
0pt
\fi
}
\fi%
% Make setting global
\global\remainingspace@perbox=\remainingspace@perbox%
}
% Produce a box that consumes all available space,
% shared evenly among all boxes of this group.
\newcounter{vfillboxes}
\newcommand{\vfillbox}[2][\dimexpr\linewidth-2\fboxrule-2\fboxsep\relax]{%
\stepcounter{vfillboxes}%
\parbox[t][\remainingspace@perbox][t]{#1}{%
#2
}%
}
% Same as previous, with additional proportiality factor.
\newcommand{\Vfillbox}[3][\dimexpr\linewidth-2\fboxrule-2\fboxsep]{%
\addtocounter{vfillboxes}{2}%
\parbox[t][2\remainingspace@perbox][t]{#1}{%
#3
}%
}
\makeatother
\begin{document}
%\resetboxestrue
\getrestofpage
Please justify all your answers to the following questions.
\begin{enumerate}
\item Is this = that?\hfill 2 points
\fbox{%
\Vfillbox{3}{%
Bla bla bla.
}%
}
\item Is that = this?\hfill 2 points
\fbox{%
\vfillbox{%
Bla bla bla.
}%
}
\end{enumerate}
\saverestofpage
\pagebreak
\getrestofpage
\begin{enumerate}
\item Is this = that?\hfill 2 points
\fbox{%
\vfillbox{%
Bla bla bla.
}%
}
\item Is that = this?\hfill 2 points
\fbox{%
\vfillbox{%
Bla bla bla.
}%
}
\item Is this = that?\hfill 2 points
\fbox{%
\vfillbox[\dimexpr\linewidth-2\fboxrule-2\fboxsep]{%
Bla bla bla.
}%
}
\item Is this = that?\hfill 2 points
\fbox{%
\vfillbox[\dimexpr\linewidth-2\fboxrule-2\fboxsep]{%
Bla bla bla.
}%
}
\end{enumerate}
\saverestofpage
\end{document}