避免在节前分页

避免在节前分页

在我制作的布局中,正文排版为两列,在每一节的末尾,两列会保持平衡,并出现一个装饰性的分节符。实际使用时,它看起来是这样的:

正确的方法

我试图让装饰部分始终与节的末尾出现在同一页上,但效果并不好。以下是 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}}

我想就是这样。为了测试,我还增加了\textheight5pt,这样我们就得到了

在此处输入图片描述

并发出警告:

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) 的演变过程,并介绍了很久以前发生的许可证“战争”的一些历史,因此我认为它本身就值得一读。

相关内容