LaTeX 的 \if@nobreak 机制是什么以及它如何工作?

LaTeX 的 \if@nobreak 机制是什么以及它如何工作?

许多与 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在我的示例中找到Tin时。在此阶段,安全地插入了,因此标志被关闭,以便下一个或其他任何标志不会添加不需要的标志。对于此机制,一切都是全局完成的,因为钩子可以位于组内。一个简单的例子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)之后,那么就会阻止中断:这就是将以下文本与标签保持在一起的原因,而标签本身又与节标题保持在一起。

相关内容