了解框架章节标题上方的“可拉伸”负垂直空间

了解框架章节标题上方的“可拉伸”负垂直空间

这个问题和我之前的问题有些相关使用 KOMA-script 在章节标题上方/下方添加线条,使章节的水平盒子溢出,因为问题(部分)发生在添加顶线和底线的各种/所有方法上(不仅仅是mdframed我发现最容易控制的方法)。

给出以下最小示例来展示该问题

\documentclass[
    parskip=full,
    open=any,
]{scrreprt}
\usepackage{mdframed}
\usepackage{lipsum}

\RedeclareSectionCommand[
    beforeskip=0pt,
    afterskip=0pt,
]{chapter}

\newmdenv[
    skipabove=16pt, % why is this necessary?
    leftline=false,
    rightline=false,
    innerleftmargin=0.5mm,
    innerrightmargin=0.5mm,
    innertopmargin=4pt,
    innerbottommargin=1pt,
    linewidth=.6pt,
]{chapterframe}

\makeatletter
\renewcommand{\chapterlinesformat}[3]{%
\begin{chapterframe}%
    \raggedchapter%
    \@hangfrom{\vphantom(#2}{#3}%
\end{chapterframe}%
\nointerlineskip}

\widowpenalty10000
\clubpenalty10000
\begin{document}
\flushbottom
\chapter{Foo}
\lipsum[1-4]
\chapter{Bar}
\lipsum[1-4]

% just the right amount of text to cause paragraph spacing to stretch
Fusce mauris. Vestibulum luctus nibh at lectus. Sed
bibendum, nulla a faucibus semper, leo velit ultricies
tellus, ac venenatis arcu wisi vel nisl. Vestibulum
diam. Aliquampellentesque, augue quis sagittis posuere,
turpis lacus congue quam, in hendrerit risus eros eget
felis.
\end{document}

我遇到以下两个问题:

  1. 我需要定义一个跳过,以便标题的上行不会超出文本框。这似乎表明,inbeforeskip不会\RedeclareSectionCommand导致零跳过,而是负跳过。
  2. 当拉伸段落间距以防止出现孤行/寡行时,章节标题相对于页面的位置会发生变化,因为显然负空间不仅存在而且还“可拉伸”。

因此,我的问题是:为什么会有负空间,我该如何删除它,或者至少防止它拉伸,以便章节标题保持在固定位置?

经过一些实验,下面的方法似乎可以解决问题,但我仍然想知道原因(也欢迎更简洁的解决方案!):

\makeatletter
\renewcommand{\chapterlinesformat}[3]{%
\makebox[.65\linewidth][l]{%
\begin{minipage}{\linewidth}%
\vspace{1.6pt}
\begin{chapterframe}%
    \raggedchapter%
    \@hangfrom{\vphantom(#2}{#3}%
\end{chapterframe}%
\end{minipage}%
}}

需要\makebox避免原始的水平框过满问题,而 minipage 似乎解决了间距问题。仍然有一个轻微的负值,但显然是恒定的垂直空间 1.6pt。这可能是也可能不是行宽和内底边距的总和。

答案1

查看 showbox 输出,代码正在补偿\parskip但仅是其自然长度,因此您最终会得到(仅)标题之前的拉伸分量。我没有追踪确切的位置,但如果您本地使用固定 parskip,则两个标题都会出现在同一点:

\documentclass[
    parskip=full,
    open=any,
]{scrreprt}
\usepackage{mdframed}
\usepackage{lipsum}

\RedeclareSectionCommand[
    beforeskip=0pt,
    afterskip=0pt,
]{chapter}

\newmdenv[
    skipabove=16pt, % why is this necessary?
    leftline=false,
    rightline=false,
    innerleftmargin=0.5mm,
    innerrightmargin=0.5mm,
    innertopmargin=4pt,
    innerbottommargin=1pt,
    linewidth=.6pt,
]{chapterframe}

\makeatletter

\showoutput
\showboxdepth=1
\renewcommand{\chapterlinesformat}[3]{%
\begin{chapterframe}%
    \raggedchapter%
    \@hangfrom{\vphantom(#2}{#3}%
\end{chapterframe}%
\nointerlineskip}

\widowpenalty10000
\clubpenalty10000
\begin{document}
\flushbottom
{\parskip=1\parskip\chapter{Foo}}

\lipsum[1-4]

{\parskip=1\parskip\chapter{Bar}}
\lipsum[1-4]

% just the right amount of text to cause paragraph spacing to stretch
Fusce mauris. Vestibulum luctus nibh at lectus. Sed
bibendum, nulla a faucibus semper, leo velit ultricies
tellus, ac venenatis arcu wisi vel nisl. Vestibulum
diam. Aliquampellentesque, augue quis sagittis posuere,
turpis lacus congue quam, in hendrerit risus eros eget
felis.
\end{document}

原版制作

Underfull \vbox (badness 1783) has occurred while \output is active
\vbox(595.80026+0.0)x418.25555, glue set 2.61316
.\write-{}
.\write1{\@writefile{toc}{\protect \contentsline {chapter}{\protect \numberline
 \ETC.}
.\write1{\@writefile{lof}{\protect \addvspace {10\p@ }}}
.\write1{\@writefile{lot}{\protect \addvspace {10\p@ }}}
.\glue(\topskip) 11.0
.\vbox(0.0+0.0)x0.0, glue set 13.6fil []
.\glue -13.6 plus -1.36008
.\glue -13.6

加上 -1.360008 永远不会得到补偿,并且由于页面未满,任何数量的拉伸组件都可以拉伸以填满空间。

相关内容