\let 和 sneaky 重新定义是原始宏的包装器:环境中有类似的东西吗?

\let 和 sneaky 重新定义是原始宏的包装器:环境中有类似的东西吗?

假设我正在使用一些\foo几乎可以完成我想要的宏,但实际上我想在输出的两侧添加空格\foo。我可以执行以下操作:

\let\tempfoo\foo
\renewcommand\foo{\hspace{1em}\tempfoo\hspace{1em}}

这重新定义了\foo它之前所做的事情,并在两侧增加了一些额外的空间。有没有办法以同样的方式“修补”环境?我想问题实际上是我如何\let处理环境?

答案1

环境foo定义了两个宏\foo\endfoo。您可以像已经做的那样重新定义它们:

\let\origfoo\foo
\let\endorigfoo\endfoo
\renewenvironment{foo}
    {<your stuff>\origfoo<your stuff>}
    {<your stuff>\endorigfoo<your stuff>}

但是,使用该包etoolbox及其宏可以使生活变得更轻松。

答案2

最实用的方法是利用电子工具箱的实用功能:

\preto\foo{\hspace{1em}}
\appto\foo{\hspace{1em}}

例如,带有“明显参数”的命令会出现问题\section。如果你查看 的输出\show\section,你会发现它有参数。这是 LaTeX 中经常使用的一种技术,因为它更有效率。实际上\section被转换成

\@startsection{...}{...}{...}{...}{...}

并且\@startsection参数;您会看到\section提供了前五个,第六个是后面的\section(还有更多,因为可以有一个 * 或一个可选参数,但我们保持简单)。

\appto对于类似的命令使用技巧\section将导致灾难,因为添加的内容将提供第六个参数\@startsection,这显然不是想要的。

正如 Herbert 所说,你也可以将\preto\appto用于环境,如果环境是,则使用\foo和,前提是环境没有参数。如果参数是命令的一部分(即它不是“明显的”),则可以使用和;如果参数是明显的(例如的情况),则可以使用和\endfoofoo\pretocmd\apptocmd\tabular\appto\apptocmd 一定不可以使用,但\preto\pretocmd相当安全。

答案3

对于环境,您可以使用\AtBeginEnvironment\AtEndEnvironment\BeforeBeginEnvironment\AfterEndEnvironment提供的etoolbox.etoolbox为环境添加一些钩子。您也可以使用\appto\preto来修补\foo\endfoo。这两种方法的工作方式不同。

一个例子:

\documentclass{article}
\usepackage{etoolbox}

\newenvironment{foo}{(}{)}

\begin{document}
\begin{foo}foo\end{foo}

\BeforeBeginEnvironment{foo}{[}
\AfterEndEnvironment{foo}{]}
\begin{foo}foo\end{foo}

\appto\foo{\{}
\preto\endfoo{\}}
\begin{foo}foo\end{foo}

\end{document}

答案4

其他鬼鬼祟祟方法是在宏的开头或结尾添加一些内容。LaTeX 提供了\g@addto@macro附加到现有宏的命令,而 etoolbox 提供了附加prepending和添加的命令。以下代码修改了\begin{document}

\documentclass{article}
\makeatletter
\g@addto@macro{\document}{ Oh! I see!}
\makeatother
\begin{document}
\end{document}

相关内容