![用多色平衡底部](https://linux22.com/image/306758/%E7%94%A8%E5%A4%9A%E8%89%B2%E5%B9%B3%E8%A1%A1%E5%BA%95%E9%83%A8.png)
我想平衡所有列的底部。但只有最后一列不平衡。它的高度只有一半textheight
。
如果删除%
最后一页%\columnbreak
,最后一列的页码将保持平衡。但是会出现没有文本且只有两条垂直线的第二页。
我应该怎么做才能平衡所有列的底部而不出现第二页?
\documentclass{article}
\usepackage{multicol}
\multicolsep0pt
\columnseprule.4pt
\pagestyle{empty}
\begin{document}
\noindent
\textbf{\large Examination}\smallskip\hrule
\begin{multicols*}{3}
\begin{enumerate}
\item Qutetion
\vfill
\begin{flushright}\underline{Answer\hspace{4em}}\end{flushright}
\columnbreak
\item Qutetion
\vfill
\begin{flushright}\underline{Answer\hspace{4em}}\end{flushright}
\columnbreak
\item Qutetion
\vfill
\begin{flushright}\underline{Answer\hspace{4em}}\end{flushright}
%\columnbreak
\end{enumerate}
\end{multicols*}
\end{document}
答案1
围绕平衡和多列确实有太多相互冲突的用例 :-( 并且 TeX 的支持太少也无济于事。
分析此请求,很明显,期望所有三列看起来都相同。不幸的是,这不是multicol*
实现的用例(如果确实存在有缺陷的 1.8f 版本确实实现了这一点,那么这实际上不会改变这一点)。
实现的用multicol*
例如下:
- 每一列都填满,直到到达页面底部
- 然后我们开始新的专栏
- 最后一列底部填充了空白,这样这一列“不完整”就不会散开。
这是模仿\twocolumn
LaTeX 的工作方式或完成文档(或处理\newpage
)的方式。因此,您得到的是
这是“正确的”,因为本质上 a\vfill
被添加到了底部。现在考虑到该列已经包含 a,\vfill
我们得到了相等的强度,因此单词 Answer 被添加到了中间。
现在人们可以争论这是否应该是 a\vfill
或者仅仅是 a \vfil
(也许后者更合适,因为这也是 LaTeX 所使用的)但事实是自从引入以来multicol
就一直在使用双倍强度。\vfill
multicol*
因此让我们暂时通过替换这样的内部定义来改变这种情况:
\renewcommand\vfillmaxdepth{\vskip 0pt plus 1fil minus \maxdepth}
(通常里面有“填充”)。那么这给我们带来了什么?
嗯,所以也不完全正确。你知道为什么吗?
好吧,问题在于这 3 列并不相同。最后一列是enumerate
环境的结束,这增加了额外的垂直空间,我们可以在上面清楚地看到。第一列顶部没有类似空白的原因是,在开头抑制multicol
了这种空白,因为这是一种常见的用例(再次,您会看到存在判断调用,并且可能存在您不想抑制这种空白的情况)。
那么我们最后该如何去掉这个多余的空间呢?
事实证明这并不容易。当然,您可以找出这里使用的参数是什么,并将其设置为零,但 a) 该参数在 LaTeX 中的所有“显示环境”之间共享,并且 b) 这还不够。
让我们尝试一下
\vskip-\lastskip % not really LaTeX but there you are
之后\end{enumerate}
。我们几乎到达了目标,但仍然不正确,因为我们得到
我叠加了几个xxxx
es,这样更容易看清发生了什么。那么为什么最后一列的文本仍然比其他列高呢?原因是前两列底部没有任何空格,但最后一列有一些。我们用上面的命令将其取消,但它仍然是一个空格,只是先是正空格,然后是负空格。
但问题是,任何这样的空间意味着最后一列的深度基本上被忽略,因此在前两列中,底部位于单词“Answer”的基线,并且\underline
实际上位于列底部下方(我们有一个深度)而在最后一列中,底部是印刷材料结束的地方,即我们没有深度并且所有材料都在列内。
因此,人们真正需要的\end{enumerate}
是
\vskip-\lastskip % drop the extra space from enumerate
\vskip-\prevdepth % back up by the depth of the last lin
只有这样你才能得到
现在这还不是应该的样子,如果你multicol*
用替换multicol
,你会注意到上面的内容是需要的(因为\vfill
在最后一列的末尾添加了 no),但它也不起作用,你最终会得到
(再次与 xxxx 叠加)因此最后一列偏离了这个\prevdepth
量。
现在,我猜这是一个错误(在 1.8i 版本中),我担心我需要对此进行深入研究......而且我之前还有很多问题......\prevdepth
处理似乎是一场噩梦。
更新
我更新了multicol
以直接支持此用例,因为我认为这可以在不损害其他场景的情况下完成。基本方法是
- 首先
\end{multicols*}
备份\lastskip
(如果有空间,比如说从环境结束,我们实际上并不需要它) - 然后后退
\prevdepth
(这样我们就位于最后一个框的基线,如果有的话) - 然后插入一个
\vfil
(一个 l),这样默认情况下该列被设置为参差不齐。
现在,如果\fill
列内有一个,它将很好地对齐到底部(除非有多个垂直空间,因为我们只删除了最后一个)。
如果用户确实想要一个特定的空间,那么最后的\vspace*
那个就会为他做到这一点。
完整的方法稍微复杂一些,这就是为什么它需要更多的测试,但如果一切顺利,它将出现在 v1.8j 中。
答案2
您已经使用了multicols*
而不是multicols
停止平衡。
如果没有,*
则列是平衡的,产生: