考虑以下两个宏,唯一的区别是一个宏在组内具有环境:
\documentclass{article}
\makeatletter
\newcommand\thisworks{%
{\begin{center}
$\ast$
\end{center}}
\@afterindentfalse
\@afterheading}
\newcommand\thisdoesnt{%
\begin{center}
$\ast$
\end{center}
\@afterindentfalse
\@afterheading}
\makeatother
\usepackage{lipsum}
\begin{document}
\lipsum[1]
\thisworks
\lipsum[5]
\thisdoesnt
\lipsum[42]
\end{document}
为什么第一个会抑制缩进而第二个却不会?
答案1
快速浏览一下的定义,\end{center}
我们发现它只是结束了trivlist
,
\def\endcenter{\endtrivlist}
现在至于为什么 Lamport 会使用 来trivlist
定义centering
并间接地定义center
宏是另一个问题的主题,现在只需说他非常喜欢它们,尽管我相信他这样做有一些正当的理由。
稍微改变你的代码并引入一个trivlist
你可以观察到的效果:
\documentclass{article}
\makeatletter
\newcommand\thisworks{%
$$\ast$$
\@afterindentfalse
\@afterheading}
\newcommand\thisdoesnt{%
{\begin{trivlist}\item\end{trivlist}}
$$\ast$$
\@afterindentfalse
\@afterheading
}
\makeatother
\usepackage{lipsum}
\begin{document}
\lipsum[1]
\thisworks
\lipsum[5]
\thisdoesnt
\lipsum[42]
\end{document}
如果您取消注释该行的分组括号\begin{trivlist}
,您将看到效果。代码全部交织在 source2e.pdf 中。
为了更好地理解 LaTeX 的错误行为,我将用另一个最简单的例子来说明:
\documentclass{article}
\begin{document}
This is the normal behavior of a:
\begin{trivlist}\item list\end{trivlist}
trivlist that is not enclosed in a group.
If you enclose the list in a group the lines after the list:
{\begin{center} center\end{center}}
are indented. LaTeX is buggy in this respect.
\end{document}
其结果是:
如果您对命令进行分组trivlist
或center
操作,则会导致相同的错误行为。在您的示例中,后者允许 \@afterindentfalse\@afterheading
生效,因为它可以在段落开头应用 everypar 或缩进,而在上面的第一个示例中,它不能,因为以下文本被视为上一段的最后一部分。
答案2
\endtrivlist
调用\@endparenv
将导致\@doendpe
执行“在段落制作环境之后立即抑制文本中的段落缩进”(LaTeX2e 源,第 227 页)。\@doendpe
将覆盖。请注意,您可以通过在 MWE 文档正文中的后一行中添加(注释符号)来\@afterindentfalse\@afterheading
抑制以下段落的缩进 。%
\thisdoesnt
也可以看看\@doendpe 到底起什么作用?