\ignorespaces 和 \ignorespacesafterend 之间有什么区别?

\ignorespaces 和 \ignorespacesafterend 之间有什么区别?

\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 宏)。

相关内容