如何将列表中的最后 n 行保持在一起?

如何将列表中的最后 n 行保持在一起?

我使用 lstlisting (listins-package) 定义了一个大型列表。现在列表已超过三页。最后一页只有一行(最后一行)列表。看起来不太好看,因为该行仅包含一个括号。

如果列表在新页面上结束,是否有办法确保列表末尾出现至少 n(即三)行?

答案1

可能性是存在的,但实现起来有点困难。该listings包包含许多钩子,但不幸的是,没有一个钩子能够直接实现这一点(至少我快速阅读后没有看到一个)。

问题在于,列表中的每一行实际上都是一个段落,因此\parskip行与行之间会有一些断点,这些断点构成了有效的断点。因此,需要的是添加一些断点,\nobreak以防止出现断点。这发生在命令中\lst@NewLine,因此主要的技巧是修补此命令:

\makeatletter

\def\lst@NewLine{%
    \ifx\lst@OutputBox\@gobble\else
        \par
        \ifnum\c@lstnumber > \@nobreaklinepoint \relax  \nobreak \fi  % <-- new code
        \noindent \hbox{}%
    \fi
    \global\advance\lst@newlines\m@ne
    \lst@newlinetrue}

现在\@nobreaklinepoint应该是列表中倒数第三行的行号。好吧,这是第二个问题:我们不知道在处理过程中列表的行数。因此,为了自动获取此信息,需要记录列表中的行,将它们写入辅助文件(或类似文件),并在下一次排版运行中使用记录的值。--- 不,我还没有这样做 :-) 也许其他人有耐心。

相反,我采用了简单的方法让用户手动指定:

\def\lstnobreakafterline#1{\gdef\@nobreaklinepoint{#1}}

因此,如果您的列表有 15 行,并且您想确保最后 3 行始终在一起,则需要说\lstnobreakafterline{13}。所以需要一点计数,抱歉。

现在所有这些都应该只发生在下一个列表中,所以我们必须做更多的工作:

\lst@AddToHook{ExitVars}{\lstnobreakafterline{\maxdimen}}
\lstnobreakafterline{\maxdimen}
\makeatother

这里我们可以使用内置钩子。我们将数字默认为,\maxdimen并在列表环境结束时将其重置。

明显的改进可能性:\lstnobreakafterline我们可以定义一个更适合包接口的新关键字(但现在快到午夜了),当然也可以在双程系统中自动确定数字。

还有一个缺陷:如果\c@lstnumber对行进行编号,实际上是列表将使用的行号。因此,如果编号持续到多个列表(这可能取决于设置),那么这将不会在每个列表上从 1 重新开始。

尽管如此,还是享受吧;-)

相关内容