我试图对文档中的标题进行样式化,使不同大小部分的上升部分在文本区域上边缘下方留出一定空间。我想出了这个命令,用于打印标题:
\newcommand*{\@titlemargins}{% is used inside groups so the altered \topskip doesn't leak
\setlength{\topskip}{\z@}% "first line bounding box flush with top of the text area"
\vspace*{\z@}% "first line baseline is \baselineskip below the top of the textblock"
\setlength{\@leadings}{\baselineskip}\addtolength{\@leadings}{-\f@size pt}% the heading font size needs to be set before \@titlemargins
\vspace*{-\@leadings}% "ascender of the first line is flush with top of the text area"
}
% and then do \@titlemargins \vspace*{n pt} in section definitions
一开始,这似乎产生了预期的效果。然后我遇到了一个问题,我注意到带有 的页面上的\marginpar
标题太靠下。它似乎不知何故扰乱了页面顶部?
这是一个最小的例子,它省略了所有的微调并表现出意外的\marginpar
行为:
\documentclass{report}
\begin{document}
\begingroup
\setlength{\topskip}{0pt}
\vspace*{8pt}
\endgroup
I'm supposed to be 8 points below the top.
Another paragraph.
\clearpage
\begingroup
\setlength{\topskip}{0pt}
\vspace*{8pt}
\endgroup
I'm supposed to be 8 points below the top.
Another paragraph.\marginpar{And then there's a note.}
\end{document}
出乎意料的是,第二页的段落比第一页的段落要低。
我能做些什么吗\marginpar
?或者我需要使用其他方法吗\@titlemargins
?
答案1
解释在于,这\marginpar
会导致调用输出例程,随后将页面返回到页面构建器;后者随后再次插入粘合\topskip
,此时粘合已恢复其默认值(在您的示例中为 10 点)。您可以检查是否发生了同样的事情,例如,在任何包含浮点的页面上,因为浮点以类似的方式调用输出例程。
可以通过要求 TeX 显示其正在处理的列表来验证这些声明,如下面的测试代码所示:
\documentclass{report}
\showboxbreadth = 1000
\showboxdepth = 10
% \tracingonline = 1
\begin{document}
\begingroup
\setlength{\topskip}{0pt}
\vspace*{8pt}
\endgroup
I'm supposed to be 8 points below the top.
Another paragraph.
% \showlists
\clearpage
\begingroup
\setlength{\topskip}{0pt}
\vspace*{8pt}
\endgroup
I'm supposed to be 8 points below the top.
Another paragraph.\marginpar{And then there's a note.}\showlists
\showlists
\end{document}
\showlists
这是从记录文件中获取的第一个(未注释)产生的跟踪:
### horizontal mode entered at line 26
\hbox(0.0+0.0)x15.0
\OT1/cmr/m/n/10 A
\OT1/cmr/m/n/10 n
\OT1/cmr/m/n/10 o
\OT1/cmr/m/n/10 t
\OT1/cmr/m/n/10 h
\OT1/cmr/m/n/10 e
\OT1/cmr/m/n/10 r
\glue 3.33333 plus 1.66666 minus 1.11111
\OT1/cmr/m/n/10 p
\OT1/cmr/m/n/10 a
\OT1/cmr/m/n/10 r
\OT1/cmr/m/n/10 a
\OT1/cmr/m/n/10 g
\OT1/cmr/m/n/10 r
\OT1/cmr/m/n/10 a
\OT1/cmr/m/n/10 p
\OT1/cmr/m/n/10 h
\OT1/cmr/m/n/10 .
\vadjust
.\penalty -10004
.\vbox(0.0+0.0)x0.0
.\penalty -10002
spacefactor 3000
### vertical mode entered at line 0
### current page:
\write-{}
\glue(\topskip) 0.0
\rule(0.0+0.0)x*
\penalty 10000
\glue 8.0
\glue 0.0
\glue(\parskip) 0.0 plus 1.0
\glue(\baselineskip) 5.05556
\hbox(6.94444+1.94444)x345.0, glue set 141.77744fil
.\hbox(0.0+0.0)x15.0
.\OT1/cmr/m/n/10 I
.\OT1/cmr/m/n/10 '
.\OT1/cmr/m/n/10 m
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 s
.\OT1/cmr/m/n/10 u
.\OT1/cmr/m/n/10 p
.\OT1/cmr/m/n/10 p
.\kern0.27779
.\OT1/cmr/m/n/10 o
.\OT1/cmr/m/n/10 s
.\OT1/cmr/m/n/10 e
.\OT1/cmr/m/n/10 d
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 t
.\OT1/cmr/m/n/10 o
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 b
.\kern0.27779
.\OT1/cmr/m/n/10 e
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 8
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 p
.\kern0.27779
.\OT1/cmr/m/n/10 o
.\OT1/cmr/m/n/10 i
.\OT1/cmr/m/n/10 n
.\kern-0.27779
.\OT1/cmr/m/n/10 t
.\OT1/cmr/m/n/10 s
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 b
.\kern0.27779
.\OT1/cmr/m/n/10 e
.\OT1/cmr/m/n/10 l
.\OT1/cmr/m/n/10 o
.\kern-0.27779
.\OT1/cmr/m/n/10 w
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 t
.\OT1/cmr/m/n/10 h
.\OT1/cmr/m/n/10 e
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 t
.\OT1/cmr/m/n/10 o
.\OT1/cmr/m/n/10 p
.\OT1/cmr/m/n/10 .
.\penalty 10000
.\glue(\parfillskip) 0.0 plus 1.0fil
.\glue(\rightskip) 0.0
\glue(\parskip) 0.0 plus 1.0
total height 21.94444 plus 2.0
goal height 550.0
prevdepth 1.94444
您可以看到,在以
### vertical mode entered at line 0
### current page:
\topskip
在调用由 触发的输出例程之前,最初插入的胶水确实\marginpar
是
\glue(\topskip) 0.0
顺便说一下,在标题为
### horizontal mode entered at line 26
你可以看到如何命令\marginpar
触发调用:它插入
\vadjust
.\penalty -10004
.\vbox(0.0+0.0)x0.0
.\penalty -10002
在正在形成的段落的水平列表中。当段落结束时,它将被分成几行,并且的内容\vadjust
将插入到主垂直列表中结束的行下\marginpar
:这将调用输出例程(实际上,两次),因为两个\penalty
节点随后从“最近的贡献”移动到“当前页面”。
相反,第二个(未注释)的结果\showlists
如下:
### vertical mode entered at line 0
### current page:
\write-{}
\glue(\topskip) 10.0
\rule(0.0+0.0)x*
\penalty 10000
\glue 8.0
\glue 0.0
\glue(\parskip) 0.0 plus 1.0
\glue(\baselineskip) 5.05556
\hbox(6.94444+1.94444)x345.0, glue set 141.77744fil
.\hbox(0.0+0.0)x15.0
.\OT1/cmr/m/n/10 I
.\OT1/cmr/m/n/10 '
.\OT1/cmr/m/n/10 m
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 s
.\OT1/cmr/m/n/10 u
.\OT1/cmr/m/n/10 p
.\OT1/cmr/m/n/10 p
.\kern0.27779
.\OT1/cmr/m/n/10 o
.\OT1/cmr/m/n/10 s
.\OT1/cmr/m/n/10 e
.\OT1/cmr/m/n/10 d
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 t
.\OT1/cmr/m/n/10 o
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 b
.\kern0.27779
.\OT1/cmr/m/n/10 e
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 8
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 p
.\kern0.27779
.\OT1/cmr/m/n/10 o
.\OT1/cmr/m/n/10 i
.\OT1/cmr/m/n/10 n
.\kern-0.27779
.\OT1/cmr/m/n/10 t
.\OT1/cmr/m/n/10 s
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 b
.\kern0.27779
.\OT1/cmr/m/n/10 e
.\OT1/cmr/m/n/10 l
.\OT1/cmr/m/n/10 o
.\kern-0.27779
.\OT1/cmr/m/n/10 w
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 t
.\OT1/cmr/m/n/10 h
.\OT1/cmr/m/n/10 e
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 t
.\OT1/cmr/m/n/10 o
.\OT1/cmr/m/n/10 p
.\OT1/cmr/m/n/10 .
.\penalty 10000
.\glue(\parfillskip) 0.0 plus 1.0fil
.\glue(\rightskip) 0.0
\glue(\parskip) 0.0 plus 1.0
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x345.0, glue set 243.52757fil
.\hbox(0.0+0.0)x15.0
.\OT1/cmr/m/n/10 A
.\OT1/cmr/m/n/10 n
.\OT1/cmr/m/n/10 o
.\OT1/cmr/m/n/10 t
.\OT1/cmr/m/n/10 h
.\OT1/cmr/m/n/10 e
.\OT1/cmr/m/n/10 r
.\glue 3.33333 plus 1.66666 minus 1.11111
.\OT1/cmr/m/n/10 p
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 r
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 g
.\OT1/cmr/m/n/10 r
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 p
.\OT1/cmr/m/n/10 h
.\OT1/cmr/m/n/10 .
.\penalty 10000
.\glue(\parfillskip) 0.0 plus 1.0fil
.\glue(\rightskip) 0.0
\kern -1.94444
\hbox(0.0+0.0)x345.0, glue set - 76.0fil
.\glue 345.0
.\glue 11.0
.\vbox(0.0+0.0)x65.0
..\glue -6.94444
..\vbox(6.94444+12.0)x65.0
...\hbox(6.94444+0.0)x65.0, glue set 14.1667
....\hbox(0.0+0.0)x0.0
....\OT1/cmr/m/n/10 A
....\OT1/cmr/m/n/10 n
....\OT1/cmr/m/n/10 d
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 t
....\OT1/cmr/m/n/10 h
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 n
....\glue(\rightskip) 0.0
...\penalty 300
...\glue(\baselineskip) 5.05556
...\hbox(6.94444+0.0)x65.0, glue set 2.69435fil
....\OT1/cmr/m/n/10 t
....\OT1/cmr/m/n/10 h
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 r
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 '
....\OT1/cmr/m/n/10 s
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 a
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 n
....\OT1/cmr/m/n/10 o
....\OT1/cmr/m/n/10 t
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 .
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
.\glue 0.0 plus 1.0fil minus 1.0fil
\hbox(0.0+1.94444)x0.0
.\rule(0.0+1.94444)x0.0
\penalty 0
\penalty 10000
total height 42.0 plus 2.0
goal height 550.0
prevdepth 1.94444, prevgraf 1 line
如您所见,\topskip
胶水已重新插入,并具有其默认的10.0
点值,原因如前所述。
值得注意的是,上面的文字记录还显示,在命令\vspace*
和“我应该是…”框之间插入了正常的行间粘连:这意味着它们都没有在距离文本块顶部 8 点的位置运行其上边缘。您应该在它们前面加上\nointerlineskip
。
答案2
似乎使用\vspace*{-\topskip}
而不是 可以\setlength{\topskip}{0pt}\vspace*{0}
修复带有 的页面上的问题,\marginpar
同时在其他地方产生完全相同的输出。我仍然想听听是什么\marginpar
导致了这种行为。