如何限制 etoolbox 环境修补的范围?

如何限制 etoolbox 环境修补的范围?

我想使用该etoolbox软件包来修补某个环境;但是 - 我只想针对我的文档的某个特定部分进行此操作。

用花括号括起来不起作用:

\documentclass{article}
\usepackage{etoolbox}
\begin{document}
{
\AtBeginEnvironment{center}{(patched start!)}
\AtEndEnvironment{center}{(patched end!)}
\begin{center}
In center.
\end{center}
}
Out of center.

\begin{center}
In center.
\end{center}

\end{document}

第二个环境也以修补后的形式呈现。我应该怎么做?

答案1

更新

LaTeX 的 2020-10-01 版本为 LaTeX 内核添加了新的钩子机制。etoolbox现在使用该新钩子机制。这意味着下面提供的答案不再有效。

所有 LaTeX 钩子都是全局的,似乎没有简单的方法将它们变为本地的。有一种方法可以只为钩子的“下一次”使用添加代码,这与真正的本地分配不同。

\documentclass{article}
\usepackage{etoolbox}

\newrobustcmd{\AtNextBeginEnvironment}[1]{%
  \AddToHookNext{env/#1/begin}}

\newrobustcmd{\AtNextEndEnvironment}[1]{%
  \AddToHookNext{env/#1/end}}

\begin{document}
\AtNextBeginEnvironment{center}{(patched start!)}
\AtNextEndEnvironment{center}{(patched end!)}
\begin{center}
In center.
\end{center}

Out of center.

\begin{center}
In center.
\end{center}

\end{document}

另外,新的 LaTeX 钩子允许您从钩子中删除代码。这不会在关闭组中自动发生,但根据您的用例可能是一个选项。

以下是尝试通过使用带有本地辅助宏的全局钩子来复制本地钩子系统。

\documentclass{article}
\usepackage{etoolbox}

\newrobustcmd{\LocalAtBeginEnvironment}[1]{%
  \ifcsundef{ltbx@local@hook@begin@#1}
    {\AtBeginEnvironment{#1}{\csuse{ltbx@local@hook@begin@#1}}}
    {}%
  \csappto{ltbx@local@hook@begin@#1}}

\newrobustcmd{\LocalAtEndEnvironment}[1]{%
  \ifcsundef{ltbx@local@hook@end@#1}
    {\AtEndEnvironment{#1}{\csuse{ltbx@local@hook@end@#1}}}
    {}%
  \csappto{ltbx@local@hook@end@#1}}

\begin{document}
{
\LocalAtBeginEnvironment{center}{(patched start!)}
\LocalAtEndEnvironment{center}{(patched end!)}
\begin{center}
In center.
\end{center}
}
Out of center.

\begin{center}
In center.
\end{center}

\end{document}

2020-10-01 之前发布的 LaTeX 旧答案

etoolbox的文档和环境钩子都可以全局工作。幸运的是,\AtBeginEnvironment\AtEndEnvironment非常简单,可以轻松复制和更改为在本地而不是全局工作。

我们只需在本地添加钩子即可\csappto而不是\csgappto像原始定义那样全局化。

\documentclass{article}
\usepackage{etoolbox}

\newrobustcmd{\LocalAtBeginEnvironment}[1]{%
  \csappto{@begin@#1@hook}}

\newrobustcmd{\LocalAtEndEnvironment}[1]{%
  \csappto{@end@#1@hook}}

\begin{document}
{
\LocalAtBeginEnvironment{center}{(patched start!)}
\LocalAtEndEnvironment{center}{(patched end!)}
\begin{center}
In center.
\end{center}
}
Out of center.

\begin{center}
In center.
\end{center}

\end{document}

在此处输入图片描述

答案2

LaTeX 环境将其\begin{foo}代码映射到宏\foo,将其\end{foo}代码映射到宏\endfoo。因此,对于大多数环境,您可以使用经典方法使用 存储宏的原始含义\let,然后使用新定义中的原始含义重新定义\foo和(本地):\endfoo

\documentclass{article}

\begin{document}
{
% Save the old meaning ...
\let\origcenter=\center
\let\origendcenter=\endcenter
% ... and assign a new one
\def\center{%
    (patch A)%
    \origcenter
    (patch B)%
}%
\def\endcenter{%
    (patch C)%
    \origendcenter
    (patch D)%
}%
\begin{center}
In center.
\end{center}
}
Out of centering.

\begin{center}
In center.
\end{center}

\end{document}

在此处输入图片描述

这种方法的优点是您可以轻松地分别在环境的开始和结束、环境内部和环境外部添加材料。

相关内容