对于我现在正在排版的书,我需要具有以下功能的表格环境:
- 跨越多页;
- 允许
\nopagebreak
两行之间 - 不要忽略
\nopagebreak
环境开始之前
第1点和第2点可以通过环境来实现longtable
;但是最近我遇到了这样的情况:
\section{Some section}
\begin{longtable}{...}
...
将节标题留在一页上,然后longtable
在下一页开始排版。和\nopagebreak
之间没有帮助。 我发现\section
\begin
在 longtable 上提交的 bug大约 9 年前,但似乎没有人感兴趣,并且我对 TeX 不够了解,无法自己修复它。
我尝试了supertabular
包 — 它有同样的问题,并且stabular
有要点 1 和 3,但没有要点 2。有什么方法可以让它longtable
监听?或者也许有其他支持所有这三个要点的包?或者以所需的方式堆叠s 和s\nopagebreak
会更容易吗?\hbox
\vbox
答案1
编辑:正如下面的评论所指出的那样,这个解决方案有时会产生虚假的标题;我不知道如何(也没有时间)来修复它,抱歉。
有两个问题:首先,\longtable
在开始读取表格内容之前,计算当前页面是否有足够的空间。其次,它会插入一个惩罚\z@
(读作“零”),换句话说,就是允许 TeX 进行分页的地方。我们需要抑制这两者,但如果您的书中有多个 longtable,则更改不能是永久性的。
将更改放在组中似乎是不可能的(因为\longtable
我认为这会在本地重新定义输出例程),因此我添加了一个私有开关来控制是否\break
插入惩罚和惩罚。将其放在longtable\normalLTfalse
之前和\normalLTtrue
之后(而不是内部),以禁止该表的分页符和惩罚。(请注意,注释我们的行将\normalLTfalse
导致那里出现分页符。)
也许可以使用的“值”,\if@nobreak
而不必明确使用开关,但我不确定何时\if@nobreak
是\iftrue
或\iffalse
。
\documentclass{article}
\usepackage{longtable}
\usepackage{etoolbox}
\newif\ifnormalLT
\normalLTtrue
\makeatletter
\patchcmd {\LT@start}
{\vfil \break}
{\ifnormalLT \vfil \break \fi}
{\typeout{Patching longtable succeeded!}}
{\typeout{Patching longtable failed!}\ERROR}
\patchcmd {\LT@start}
{\penalty \z@}
{\ifnormalLT \penalty \z@ \fi}
{\typeout{Patching longtable succeeded!}}
{\typeout{Patching longtable failed!}\ERROR}
\makeatother
% "lipsum" is just used to have some dummy text.
% The vspace is there so that without patch
% we would have a bad page break. Remove all that.
\usepackage{lipsum}
\begin{document}
\lipsum[1-2]
\vspace{2.5cm}
\lipsum[3-4]
\section{XY}
\normalLTfalse
\begin{longtable}{c}
A \\
C \\
\end{longtable}
\normalLTtrue
\end{document}
答案2
使用 needspace 包并放在\Needspace{5\baselineskip}
节之前。(确切的值取决于类和节插入的空格。)