\ignorespaces
和之间有什么区别?\ignorespacesafterend
我是否应该使用前者而不是后者?
我见过一些示例,这些示例位于\ignorespacesafterend
环境定义的末尾,而\ignorespaces
位于打开环境的命令的末尾,但我不明白这在不同行为方面意味着什么,或者为什么需要不同的命令。难道不是只\newenvironment
为环境的开始创建一个宏,为环境的结束创建一个宏吗?那么为什么同一个命令不能在两个地方都起作用呢?
我想了解它们的不同之处,以及我是否可以\ignorespacesafterend
在任何可以使用的地方使用\ignorespaces
。
答案1
的目的\ignorespacesafterend
是吞噬 之后的空格\end{...}
,而这无法通过\ignorespaces
在环境的末尾使用代码来实现。
让我们尝试一下
\documentclass{article}
\newenvironment{foo}{%
\unskip\space(\ignorespaces
}{%
\unskip)\space\ignorespaces
}
\begin{document}
Before
\begin{foo}
bla
\end{foo}
after
\end{document}
\unskip
整个//的思路是将环境的内容放在括号中,前后各一个空格。然而,代码的结果\ignorespace
是\space
和二空格之后。为什么会发生这种情况?代码\end{foo}
扩展为(简化)
\endfoo
\@checkend{foo}
% [ ... other stuff ... ]
\if@ignore\@ignorefalse\ignorespaces\fi
其中\endfoo
扩展到的第三个参数\newenvironment
。根据此的当前定义,\endfoo
结果是
... \ignorespaces\@checkend{foo} ...
并且\ignorespaces
从未看到任何空间,所以它什么也不做。
LaTeX 内核通过引入以下行来解决这个问题
\if@ignore\@ignorefalse\ignorespaces\fi
事实上,的定义\ignorespacesafterend
非常简单
\let\ignorespacesafterend\@ignoretrue
因此,它在扩展的结果\ignorespaces
中执行。\if@ignore
\end{foo}
因此,如果你定义
\newenvironment{foo}{%
\unskip\space(\ignorespaces
}{%
\unskip)\space\ignorespacesafterend
}
你会得到预期的输出
(请注意,虽然通常将其放在\ignorespacesafterend
环境的最终代码的最后,但这并不是真正必要的。)
答案2
这\ignorespaces
是 TeX 基本命令,它在扩展后忽略所有后续空格标记,并在扫描到第一个不可扩展的无空格标记时停止这种忽略。如果我们假设用户使用此类宏后跟不需要的空格标记(这些空格标记会在水平模式下产生空格粘合),则应在宏的末尾使用它。
LaTeX 将其环境放入组中。LaTeX\newenwironment
宏允许您设置在环境末尾但在结束组标记之前处理的标记字符串。并且结束组标记是不可扩展的,因此:如果您\ignorespaces
在此处使用,则它对环境结束后不需要的空格标记没有影响。我猜这\ignorespacesafterend
是一个类似于的宏\aftergroup\ignorespaces
(但我没有确切地查看 LaTeX 宏)。