![\newline、\linebreak、\break 之间的区别](https://linux22.com/image/475103/%5Cnewline%E3%80%81%5Clinebreak%E3%80%81%5Cbreak%20%E4%B9%8B%E9%97%B4%E7%9A%84%E5%8C%BA%E5%88%AB.png)
\newline
、\linebreak
和\break
(以及)的实际定义是什么\par
?后者是 TeX 原语吗?除了一般讨论外,我找不到有关其确切功能的相关文档,所以也许有人也可以给我指出这一点。
这个问题源于我发现\newline
在某个环境中无法按预期工作\raggedleft
。我发现这\newline
有用的答案,它通过声明归结为来解释发生了什么\hfil\break
,我可以通过实验看到这是正确的,但找不到相关文件。
答案1
总结
简单策略:\newline
除非您对环境有精确的控制,否则切勿使用。
简单策略:切勿\break
在 LaTeX 中使用document
环境中使用。
较长的答案
抱歉,这不会简单。
\newline
文档开头的定义是
\@normalcr\relax
我们看到
% latex.ltx, line 7444:
\protected\def\@normalcr{%
\let \reserved@e \relax
\let \reserved@f \relax
\@ifstar{\let \reserved@e \vadjust \let \reserved@f \nobreak
\@xnewline}%
\@xnewline}
% latex.ltx, line 7454:
\def\@xnewline{\@ifnextchar[% ] bracket matching
\@newline
{\@gnewline\relax}}
% latex.ltx, line 7459:
\def\@gnewline #1{%
\ifvmode
\@nolnerr
\else
\unskip \reserved@e {\reserved@f#1}\nobreak \hfil \break
\fi}
之所以复杂,是因为的“标准”定义\newline
与 相同\\
,之后可以得到*
一个可选参数。
所以,不是,\newline
不是真的\hfil\break
。
但是,在或\newline
内保持不变flushleft
,而 则发生变化。为什么在和 内不起作用flushright
center
\\
\newline
flushright
center
内部不起作用?
让我们考虑一下
\documentclass{article}
\begin{document}
\noindent X\dotfill X
\begin{flushright}
X \newline Y
\end{flushright}
\begin{center}
X \newline Y
\end{center}
\end{document}
里面的第一行在X 的左边和右边flushright
都有粘连,所以最终的效果是将 X 居中。\hfil
center
粘连,所以最终的效果是将 X 居中。里面的情况更糟,因为现在\hfil
X 之前又有粘连了,但是二后面是胶水团\hfil
。因此 X 后面的空间是前面空间的两倍。
简单策略:\newline
除非您对环境有精确的控制,否则切勿使用。
相反,\\
内部flushright
和center
得到了不同的定义,以抵消两侧无限可拉伸的胶水。
它是什么\break
?它是从纯 TeX 继承而来的宏,为了简洁起见,在内核代码中使用。
简单策略:\break
永远不要在 LaTeX环境中使用document
。可以在定义中使用它(如果您知道它的作用)。
首选命令有\linebreak
一个重要原因:\linebreak
检查发现它的模式,否则\break
不检查。两者最终都会发出\penalty-10000
强制中断:如果在水平模式下发现,则换行,在垂直模式下发现,则分页。
如果你不小心\break
在段落之间发出,你会得到一个分页符。相反,\linebreak
段落之间只会告诉你
! LaTeX Error: There's no line here to end.
答案2
在阅读完 TeX 书籍并真正努力以更严谨的 TeX 方式进行研究后,我想添加自己的答案来补充上面的优秀答案。
首先,任何宏的含义都可以\meaning<your macro>
在 LaTeX 文档中使用并编译。或者,latex2e 或 latex3 的源代码可在latex 项目。例如,换行符宏定义如下这里或带有注释(适用于 LaTeX2e)这里。
其次,纯 TeX\break
会扩展为\linebreak
或\pagebreak
并给出最大负值(-10000),确保 TeX 引擎在该点放置换行符或新页面。这可能意味着行所在的水平盒子未满,因此不应单独使用它。相反,\hfil \break
在纯 TeX 中效果更好,它提供无限(一个“小”无穷大)胶合来填充行的其余部分。但\hfil \break
如果行过满,则单独使用它会产生轻微缺陷 - 将引入空行,如
\hbox{aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa
aa aa aa aa aa} \hfil\break aa aa aa
为了解决这个问题,上面链接的文档告诉我们,换行符定义已被修改为包括\nobreak \hfil \break
,以防止溢出框自动生成换行符。最后,\unskip
添加前缀以删除行尾的任何空格,这可能很有用。因此,我们希望\newline
与 - 相同,\unskip \nobreak \hfil \break
它本质上就是如此。下面解释了另一个答案中看到的复杂定义,本质上是同时处理\\
及其变体。
第三,\par
与在纯 TeX 中留一个空行相同。
现在,我开始解释\newline
和的复杂定义\\
。上面的答案很棒。但是,接下来我想用更具体的方式说明这一点。
首先,注意以下扩展很有用(假设是纯 LaTeX):
\newline --> \@normalcr\relax
\\ --> \@normalcr
现在,\@normalcr
有带星号和不带星号的版本。其扩展如下图所示,我使用简写\e = \reserved@e
和\f = \reserved@f
:
因此,假设我们不处于垂直模式,在这种情况下,我们将得到一个@nolnerr(“这里没有结束的行”)错误,
\@normalcr --> \unskip \relax{\relax \relax} \nobreak\hfil\break
\@normalcr[1pt] --> \unskip \vadjust{\relax \vskip 1pt} \nobreak\hfil\break
\@normalcr* --> \unskip \vadjust{\nobreak \relax} \nobreak\hfil\break
\@normalcr*[1pt] --> \unskip \vadjust{\nobreak \vskip 1pt} \nobreak\hfil\break
因此\newline
没有带星号的版本或带有 [] 分隔符的参数,所以只能进行以下扩展:
\newline --> \unskip \relax{\relax \relax} \nobreak\hfil\break\relax
\\ --> \unskip \relax{\relax \relax} \nobreak\hfil\break
\\[1pt] --> \unskip \vadjust{\relax \vskip 1pt} \nobreak\hfil\break
\\* --> \unskip \vadjust{\nobreak \relax} \nobreak\hfil\break
\\*[1pt] --> \unskip \vadjust{\nobreak \vskip 1pt} \nobreak\hfil\break
在上面的例子中,\unskip
删除行尾的任何现有空格,\nobreak \hfil
添加粘连以填充行的其余部分而不中断,然后\break
给出最大惩罚(10000)以确保断行。
\\
人们应该对及其同类的扩展要小心一点,因为许多环境重新定义\\
为上述答案所述。
从以上内容中,我得出结论,一个好的直觉是的\newline
行为或多或少像\hfil \break
(在右侧添加无限胶水然后破坏),并且也与的精简版本相同\\
(区别在于技术性 - 一个有最终的\relax
)。
其他变体包括换行符前的\vadjust{\vskip x}
(无星号版本)或(星号版本)。我有一个问题,有两个不错的答案\vadjust{\nobreak \vskip x}
这里解释这些要点。简而言之,不带星号的情况会在下一行之前引入一些垂直空间,这些空间可以被分页符吞没,而带星号的版本通常会阻止行和垂直空间之间的分页符(即它会将行移动到下一页)。后者在段落开头并不完全正确 - 请参阅上面链接的问题。