在我制作的布局中,正文排版为两列,在每一节的末尾,两列会保持平衡,并出现一个装饰性的分节符。实际使用时,它看起来是这样的:
我试图让装饰部分始终与节的末尾出现在同一页上,但效果并不好。以下是 MWE:
\documentclass[letterpaper]{article}
\usepackage{multicol}
\usepackage{etoolbox}
\usepackage{fourier-orns}
\usepackage{adforn}
\usepackage{lipsum}
\def\endsecornament{\centerline{%
\adfflowerright\hspace{-.04em}%
\raisebox{-2pt}{{\large\aldine}\hspace{-.04em}}%
\adfflowerleft}}
\AfterEndEnvironment{multicols}{\endsecornament}
\begin{document}
\begin{multicols}{2}
\lipsum[1-5]
\end{multicols}
\end{document}
输出
请注意下一页上的装饰物的摆放方式。
我已经尝试过增加\postmulticols
,如果没有足够的空间放置装饰品,它似乎会产生分页符,但没有作用。
如果没有办法解决这个问题,因为页面上没有空间,是否可以自动执行\enlargethispage
命令?
编辑:我尝试\enlargethispage
通过使用来实现一种方法
\AfterEndEnvironment{multicols}{\enlargethispage{\totalheightof{\endsecornament}}%
\endsecornament}
这样可以让装饰物适合页面。这样可以减少问题,但有时在实际操作中它还是会出现在另一页上。
答案1
问题是,multicols
首先添加平衡的列,然后垂直跳过\multicolsep
会在列后生成断点。虽然这通常是我们想要的,因为这意味着如果占用了分页符,空间就会消失,但这意味着结束环境后的任何代码都来得太晚,因此如果列在页面末尾或非常接近页面末尾结束,可能会出现在下一页。因此我们禁用
%\AfterEndEnvironment{multicols}{\endsecornament}
并以不同的方式进行
如果是这种情况,为了扩大页面,我们需要multicols
在插入跳过之前挂接到代码中来测试这一点。
%------ interface -----
\usepackage{etoolbox}
\patchcmd\endmulticols
{{multicols}\endgroup}
{{multicols}\endgroup\mcenlargepage}
{\typeout{Success!}}
{\typeout{Patch failed!}\ERROR}
此时添加的代码可以测试可用空间并根据情况执行正确的操作:
%----- code ------------
%
% #1 = min space needed
% #2 = material to be inserted before \vspace{\multicolsep}
% but with \nointerlineskip (arguable)
\newdimen \mctempdim
\def\mcenlargepagecode#1#2{%
\mctempdim \dimexpr \pagegoal-\pagetotal+\pageshrink \relax
\ifdim \mctempdim < \dimexpr #1\relax
\PackageWarning{multicol}%
{Space remaining on page:
\the\mctempdim \space < \the\dimexpr #1\relax
\MessageBreak
Enlarging page by \the\dimexpr #1-\mctempdim\relax}%
\enlargethispage{\dimexpr #1-\mctempdim\relax}%
\fi
\nointerlineskip
#2%
}
可以通过设置多个寄存器来进行参数化,但是现在我使用了一种简单的方法,即您必须根据需要定义上面的\mcenlargepage
使用方法:\mcenlargepagecode
%--- parametrization ----------
\setbox0\hbox{\endsecornament}
\def\mcenlargepage{\mcenlargepagecode{\ht0+\dp0+12pt}%
{\vspace{12pt}%
\endsecornament}}
我想就是这样。为了测试,我还增加了\textheight
5pt,这样我们就得到了
并发出警告:
Package multicol Warning: Space remaining on page: 5.0pt < 23.31198pt
(multicol) Enlarging page by 18.31198pt on input line 70.
如果我们禁用补丁,我们会得到
如果我们在页面中间结束多列显示,我们得到
因此,除了可能存在一些隐藏的障碍之外,这似乎可以满足要求。
附录
该multicol
软件包是按照 LPPL 分发的免费软件。当然,此代码也是如此。但是,由于历史原因,该multicol
许可证有一个扩展的“道德义务条款”,要求在将其用于商业应用(例如制作要出售的书籍)时考虑支付您自己选择的许可费。
本文描述了这一颇为奇怪的道德义务的历史背景LaTeX 项目公共许可证 (LPPL) 的历史回顾 - LaTeX 及更多软件的许可证 可以在 LaTeX 项目网站和 TUGboat 档案中找到。该论文的主要部分描述了 LaTeX 项目许可证 (LPPL) 的演变过程,并介绍了很久以前发生的许可证“战争”的一些历史,因此我认为它本身就值得一读。