防止在第一个列表项之后或最后一个列表项之前分页

防止在第一个列表项之后或最后一个列表项之前分页

有没有办法可以全局防止所有列表在第一个和第二个项目之间或最后一个和倒数第二个项目之间插入分页符?我可以接受在第二个项目之后和倒数第二个项目之前的分页符,但我不希望第一个项目或最后一个项目单独出现。

我知道我可以使用“\nopagebreak\@nobreaktrue”来防止在特定位置分页,但我不想手动插入它,也不知道如何通过宏自动插入它。

(我已经到处搜索了好几个小时,但找不到解决方案,而且我是 LaTeX 的初学者,所以我无法弄清楚如何自己解决这个问题。)

答案1

我已经调整了 \pagetest,这样如果您将规则缩小到 6.31in,您就可以在一页上获得所有 5 个项目。

\documentclass{article}

\newcommand{\pagecheck}[1]% #1 = legnth to end of page
{\ifvmode\vspace{-\parskip}\else\newline\fi% check for blank line between items
\rule{0pt}{#1}\vspace{-#1}}

\newlength{\pagetest}
\setlength{\pagetest}{0.55in}% adjustable

\makeatletter
\newcommand{\newaux}[2]% #1 = label, #2 = text
{\expandafter\gdef\csname AUX@#1\endcsname{#2}}

\newcommand{\getaux}[1]% #1 = label
{\@ifundefined{AUX@#1}{0}{\csname AUX@#1\endcsname}}

\newcommand{\writeaux}[2]% #1 = label, #2 = text
{\@bsphack
\write\@auxout{\string\newaux{#1}{#2}}%
\@esphack}
\makeatother

\newcounter{items}%
\newcount\itemtest
\newcount\itemno

\let\OLDitemize\itemize%
\let\endOLDitemize\enditemize%
\let\OLDitem=\item%

\renewenvironment{itemize}%
{\pagecheck{\pagetest}%
\stepcounter{items}%
\global\itemtest=\getaux{item\arabic{items}}
\global\advance\itemtest by -1
\global\itemno=0
\begin{OLDitemize}}%
{\end{OLDitemize}%
\writeaux{item\arabic{items}}{\the\itemno}}

\def\item{%
\global\advance\itemno by 1
\ifnum\itemno=\itemtest \pagecheck{\pagetest}\fi%
\OLDitem}

\begin{document}

\noindent\rule{\textwidth}{6.32in}% adjustable

\begin{itemize}
\item first
\item second
\item third
\item fourth
\item fifth
\end{itemize}

\end{document}

答案2

我一直觉得 \pagebreak[3] 没什么用。\pagecheck 可防止分页超过给定距离。对于短项目,0.5 英寸就足够了。

\documentclass{article}
\usepackage{lipsum}

\newcommand{\pagecheck}[1]% #1 = legnth to end of page
{\ifvmode\vspace{-\parskip}\else\newline\fi% check for blank line between items
\rule{0pt}{#1}\vspace{-#1}}

\begin{document}
\noindent\rule{\textwidth}{1pt}

\pagecheck{3in}
\begin{itemize}
\item \lipsum[1]
\item \lipsum[2]
\item \lipsum[3]
\pagecheck{3in}
\item \lipsum[4]
\item \lipsum[5]
\end{itemize}

\end{document}

如果您确实必须使其自动化,则可以将每个项目的项目数写入 auxout,以便下次运行 latex 时它就会知道每个项目中倒数第二个项目的位置。

答案3

我可以展示如何使用 OPmac 在纯 TeX 中设置此功能。\begitems\enditems被重新定义。第一个从 REF 文件读取数据(这与 LaTeX 类似aux)。这种读取的结果是\lastitem存储当前项目列表中项目数量的宏。第二个(\enditems)将\itemnum(即项目数量)以以下形式保存到 REF 文件中:

\sdef{ilist:number_of_list}{number_of_items}

最后,重新定义内部\startitem以便放置\nobreakif\itemnum=2或 if \itemnum=\lastitem

\input opmac
\newcount\itemlistnum
\def\readnumitems{\edef\itemlistn{\the\itemlistnum}%
   \tmpnum=0\csname ilist:\itemlistn\endcsname
   \edef\lastitem{\the\tmpnum}}
\def\writenumitems{\openref\immediate\wref\sdef{{ilist:\itemlistn}{\the\itemnum}}}
\addto\begitems{\global\advance\itemlistnum by1 \readnumitems}
\def\enditems{\par\writenumitems\egroup\iiskip}
\def\startitem{\par \advance\itemnum by1
   \ifnum\itemnum=2 \nobreak \fi
   \ifnum\itemnum=\lastitem \nobreak \fi
   \noindent\llap{\printitem}\ignorespaces}

%%% The test:

\begitems
* First
* Second
  \begitems \style n
  * nested first
  * nested second
  \enditems
* Third
* Last
\enditems

\begitems
* First
* Second
* Third
* Next
* Last
\enditems

\bye

相关内容