许多与 LaTeX 分段相关的命令在操作标志时都会出现阻塞\@nobreak
。以下示例仅供参考:
\begingroup
\parindent \z@ \rightskip \@pnumwidth
\parfillskip -\@pnumwidth
{\leavevmode
\large \bfseries #1
\leaders\hbox{$\m@th\mkern 1.5mu\cdot\mkern 1.5mu$}
\hfil \hb@xt@\@pnumwidth{\hss #2}}\par
\nobreak
\global\@nobreaktrue
\everypar{\global\@nobreakfalse\everypar{}}%
\endgroup
\fi}
(从的实现来看\l@chapter
),我希望了解为什么需要该机制以及它的具体工作原理。
答案1
该\nobreak
宏可防止当前材料后出现换行。这是标题等地方的标准:标题和后面的文本之间不应有换行符。在 LaTeX 中,常见的构造是
\section{Some section}
\label{sec:important}
Text here
仅\nobreak
在内部使用\section
,分页符将使标签与节标题保持一致,但文本可能会分离。为了防止这种情况,LaTeX 在节代码中设置了标志。这将由(或者更确切地说是由内部命令)\@nobreak
拾取,并插入第二个分页符。结果是节、标签和文本的块无法插入分页符。\label
\protected@write
\nobreak
要关闭该标志,\everypar
请使用钩子。TeX 在开始一个段落时会插入该钩子,例如,当 TeX在我的示例中找到T
in时。在此阶段,安全地插入了,因此标志被关闭,以便下一个或其他任何标志不会添加不需要的标志。对于此机制,一切都是全局完成的,因为钩子可以位于组内。一个简单的例子Text here
\nobreak
\label
\section{Some section}
\label{sec:important}
{\texttt Text here}
这意味着本地旗帜可能会被“卡住”。构造
\everypar{\global\@nobreakfalse\everypar{}}
意味着不仅标志被清除,而且重置本身也被删除,不再执行进一步的操作。
以上所有方法最明显地适用于章节标题,但在几个地方使用了相同的机制(搜索latex.ltx
以@nobreak
查看所有方法)。在问题的示例中,我们正在查看目录中显示的部分。插入部分时,在下一章/节/其他内容之前不允许中断,而章节/节之间允许中断。要了解为什么\@nobreak
必须设置标志,请查看 的标准定义\l@chapter
:
\newcommand*\l@chapter[2]{%
\ifnum \c@tocdepth >\m@ne
\addpenalty{-\@highpenalty}%
\vskip 1.0em \@plus\p@
\setlength\@tempdima{1.5em}%
\begingroup
\parindent \z@ \rightskip \@pnumwidth
\parfillskip -\@pnumwidth
\leavevmode \bfseries
\advance\leftskip\@tempdima
\hskip -\leftskip
#1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
\penalty\@highpenalty
\endgroup
\fi}
它所做的第一件事是使用\addpenalty
,如果没有该标志,它将撤消插入 的\@nobreak
工作。(您可以通过使用适当设置的演示文件重新定义来轻松测试这一点。)但是,将检查标志作为其工作的一部分:启用该标志后,不会添加任何额外的惩罚,因此仍然可以防止在章节行后出现分页符。\nobreak
\l@part
\l@part
\addpenalty
\@nobreak
关于的注释\protected@write
。内容如下
\begingroup
\let \thepage \relax
#2%
\let \protect \@unexpandable@protect
\edef \reserved@a {\write #1{#3}}%
\reserved@a
\endgroup
\if@nobreak
\ifvmode
\nobreak
\fi
\fi
从而测试无中断标志。如果 TeX 处于垂直模式,因为它位于 a \section
(以标记结尾\par
)之后,那么就会阻止中断:这就是将以下文本与标签保持在一起的原因,而标签本身又与节标题保持在一起。