考虑以下 MWE:
\documentclass{article}
\usepackage{lipsum}
\usepackage{booktabs}
\begin{document}
\lipsum[1]
\clearpage
\begin{table}[htbp]%
\centering%
\caption{Test table.}%
\begin{tabular}{lcc}%
\toprule
a & b & c \\
\bottomrule
\end{tabular}%
\end{table}%
\end{document}
如下面的输出所示,表格的标题低于另一页的第一行文本,在我看来,当使用双页模式处理文档时,这看起来不太好。如果将表格放在文本中间的某个位置,一切看起来都很好。
这是出于某种原因而我没意识到的预期行为吗?如果不是,我该如何解决这个问题?
编辑:我刚刚意识到(感谢 Martin 给我这个想法)这种情况只有在设置标题时才会发生多于表,如果它是以下:将标题移至表格末尾会导致表格第一行 ( a b c
) 的基线为几乎(不完全是,但考虑到)足够接近,看起来很好\toprule
)与对立文本的基线处于相同的高度。
答案1
有两个问题。
\abovecaptionskip
,\belowcaptionskip
标准类总是假设标题以下对象。因此该类在标题上方和标题下方book
设置了一个空间。10pt
0pt
在您的例子中,表格标题位于表格上方,因此\abovecaptionskip
和的值\belowcaptionskip
应该交换。例如,包caption
为您执行此操作:
\documentclass{article}
\usepackage{lipsum}
\usepackage{booktabs}
\usepackage{caption}
\usepackage[pass,showframe]{geometry}
\begin{document}
\lipsum[1]
\clearpage
\begin{table}[htbp]%
\centering%
\caption{Test table.}%
\begin{tabular}{lcc}%
\toprule
a & b & c \\
\bottomrule
\end{tabular}%
\end{table}%
\end{document}
\topskip
TeX/LaTeX 会尝试对齐页面的第一行。TeX 知道一个跳过寄存器\topskip
。如果结果为负数,则此空间会减少第一行的高度,或设置为零。然后将生成的粘连添加到页面顶部。LaTeX 的默认值\topskip
是字体大小(10pt
、11pt
或12pt
)。
如果顶部浮动,我们有一个高度较大的框,因此插入的\topskip
为零。但是,第一页包含一个高度为 的正常行6.94444pt
。\topskip
为10pt
,因此3.05556pt
插入 。
以下补丁\topcaptionfix
试图弥补这一点:
在包的帮助下,
zref-savepos
当前垂直位置被记录在.aux
文件中作为标签。对于顶部放置的浮动,.aux
文件写入标签:\zref@newlabel{zref@1}{\posy{43889459}}
因此垂直位置为
43889459sp
。因此,如果浮动对象的垂直位置较小/较低,则此修复不适用。需要估计第一行的高度。代码假设标题使用普通字体,且字体不大于大写字母 (
A
-Z
)。可以通过可选参数指定不同的文本。默认值为Table
。如果标题使用不同的字体/大小,则需要在每行指定它们\settoheight
。caption 包还添加了
\strut
s。它们是不可见的对象,占据 的垂直空间\baselineskip
。有时它有助于对齐标题行。此功能可以通过选项 进行配置strut
,例如可以通过 将其关闭\captionsetup{strut=off}
。最后,将第一行的预估高度、的高度
\strut
(如果设置)与的值\topskip
进行比较,计算出需要插入的空间,以纠正浮动标题的位置。
示例文件:
% \showboxbreadth=\maxdimen
% \showboxdepth=\maxdimen
\documentclass{article}
\usepackage{lipsum}
\usepackage{booktabs}
\usepackage{caption}
\usepackage{zref-savepos}
\usepackage[pass,showframe]{geometry}
\makeatletter
\zref@require@unique
\providecommand*{\zref@unique@next}{%
\stepcounter{zref@unique}%
}
\providecommand*{\zsaveposy}{\zsavepos}
\newcommand*{\topcaptionfix}[1][Table]{%
\zref@unique@next
\zsaveposy{\thezref@unique}%
\zifrefundefined{\thezref@unique}{%
}{%
\ifdim\zposy{\thezref@unique}sp<43889459sp %
\else
\begingroup
% estimated height of the first line of the caption
\settoheight{\dimen@}{#1}%
\caption@ifstrut{%
\ifdim\dimen@>\ht\strutbox
\ifdim\topskip>\dimen@
\vskip\dimexpr\topskip-\dimen@\relax
\fi
\else
\ifdim\topskip>\dimen@
\vskip\dimexpr\topskip-\ht\strutbox\relax
\fi
\fi
}{%
\ifdim\topskip>\dimen@
\vskip\dimexpr\topskip-\dimen@\relax
\fi
}%
\endgroup
\fi
}%
}
\makeatother
\begin{document}
\lipsum[1]
% \showlists
\clearpage
\begin{table}[htbp]%
\centering
\topcaptionfix
\caption{Test table.}%
\begin{tabular}{lcc}%
\toprule
a & b & c \\
\bottomrule
\end{tabular}%
\end{table}%
% \showlists
\end{document}
对于熟悉 TeX 盒子表示的人来说,可以启用注释行\showbox...
和\showlists
。然后 TeX 会将当前垂直列表打印到.log
文件中。例如,第二页的开头(带有 的变体strut
):
### current page:
\write-{}
\glue(\topskip) 0.0
\vbox(41.72083+0.0)x345.0
.\pdfsavepos
.\write1{\zref@newlabel{zref@1}{\posy{\Z@C@posy }}}
.\glue 1.60004
.\write1{\@writefile{lot}{\protect \contentsline {table}{\protect \numberline \ ETC.}
.\glue 0.0
.\glue(\parskip) 0.0
.\hbox(8.39996+3.60004)x345.0
插入带有值的胶水1.60004pt
来修正表格标题的位置。
包geometry
提供了选项showframe
,允许对结果进行可视化控制:
第 1 页:
第2页:
答案2
嗯,这是一种功能……
浮动框在设置之前不知道它是否将被放置在页面顶部,并且浮动放置当它将其放置在页面顶部时并不知道框内有什么。
可以使设置取决于位置,但它会深入到输出例程中的 latex 内部代码中,因此可能与某些东西不兼容。请参阅
答案3
一种方法是使用 float 包来重新设置表格环境的样式。例如代码:
\documentclass{article}
\usepackage{lipsum}
\usepackage{booktabs}
\usepackage{float}
\floatstyle{plaintop}
\restylefloat{table}
\begin{document}
\lipsum[1]
\clearpage
\begin{table}[htbp]%
\centering%
\caption{Test table.}%
\begin{tabular}{lcc}%
\toprule
a & b & c \\
\bottomrule
\end{tabular}%
\end{table}%
\end{document}
会给: