假设我使用电子工具箱命令如\AtBeginEnvironment
或\AfterEndEnvironment
等。我如何在稍后阶段撤消这些更改?
\documentclass{article}
\usepackage{etoolbox}
\let\olditemize\itemize
\let\oldenditemize\enditemize
\AfterEndEnvironment{itemize}{bleat bleat}
\begin{document}
\begin{itemize}
\item This is an item.
\end{itemize}
\let\itemize\olditemize %Would like to undo the change
\let\enditemize\oldenditemize %now, but this doesn't help.
\begin{itemize}
\item This is another item.
\end{itemize}
\end{document}
答案1
首先请注意,\BeforeBeginEnvironment
和\AfterEndEnvironment
不会修补环境本身。它只会向钩子添加材料。etoolbox
将这些钩子的使用修补到\begin
和。这就是为什么将和重置为其原始定义不会改变任何内容的\end
原因。\itemize
\enditemize
但你可能只是取消定义环境结束钩子itemize
:
\documentclass{article}
\usepackage{etoolbox}
\AfterEndEnvironment{itemize}{bleat bleat}
\begin{document}
\begin{itemize}
\item This is an item.
\end{itemize}
\csundef{@afterend@itemize@hook}% undefine the end hook of itemize
\begin{itemize}
\item This is another item.
\end{itemize}
\end{document}
\csundef
是一个etoolbox
命令,\@afterend@itemize@hook
是环境的环境结束钩子itemize
。环境开始钩子将是\@beforebegin@itemize@hook
。
也许可以建议类似\CleanBeforeBeginEnvironment
或的命令的功能请求。\CleanAfterBeginEnvironment
选择:如果你只想删除一些内容而不是全部,你可以尝试以下操作:
\documentclass{article}
\usepackage{etoolbox}
\newrobustcmd*{\RemoveFromAfterEndEnvironment}[2]{%
\expandafter\patchcmd\csname @afterend@#1@hook\endcsname{#2}{}%
}
\AfterEndEnvironment{itemize}{bleat bleat\par}{}{}
\AfterEndEnvironment{itemize}{don't remove this\par}{}{}
\begin{document}
\begin{itemize}
\item This is an item.
\end{itemize}
\RemoveFromAfterEndEnvironment{itemize}{bleat bleat\par}{}{}
\begin{itemize}
\item This is another item.
\end{itemize}
\end{document}
的第三和第四个参数\RemoveFromAfterEndEnviroment
与 的第三和第四个参数相同\patchcmd
。
答案2
可能有官方的方法,但是定义一个新命令\AfterEndItemize
来指定您想要在之后做什么\end{itemize}
,然后使用\renewcommand
更改\AfterEndItemize
为不执行任何操作似乎有效:
\documentclass{article}
\usepackage{etoolbox}
\newcommand{\AfterEndItemize}{bleat bleat}%
\AfterEndEnvironment{itemize}{\AfterEndItemize}
\begin{document}
\begin{itemize}
\item This is an item.
\end{itemize}
%
\renewcommand{\AfterEndItemize}{}%
\begin{itemize}
\item This is another item.
\end{itemize}
\end{document}
答案3
另一种方法是:使用布尔开关。方便地etoolbox
提供此类开关。比较我的问题和etoolbox:布尔开关中的环境挂钩看看这个:
\documentclass{article}
\usepackage{setspace}
\doublespacing
\usepackage{etoolbox}
\newbool{tightspace}
\setbool{tightspace}{false} % that's the default state, so
% it's here only for clarity
%----------------------------%
\BeforeBeginEnvironment{itemize}{%
\ifbool{tightspace}{% true part:
\begin{spacing}{0.9}
}{%
% false part empty - should do nothing
}%
}
\AfterEndEnvironment{itemize}{%
\ifbool{tightspace}{% true part:
\end{spacing}
}{%
% false part
}%
}
\usepackage{lipsum}
\begin{document}
\begin{itemize}
\item \lipsum[1]
\end{itemize}
\begingroup
\setbool{tightspace}{true}
\verb|\setbool{tightspace}{true}| inside a group:
\begin{itemize}
\item \lipsum[2]
\end{itemize}
\endgroup
And from now all outside of groups:
Here is \verb|\setbool{tightspace}{false}| in effect:
\begin{itemize}
\item \lipsum[3]
\end{itemize}
\verb|\setbool{tightspace}{true}|:
\setbool{tightspace}{true}
\begin{itemize}
\item \lipsum[4]
\end{itemize}
And again \verb|\setbool{tightspace}{false}|:
\setbool{tightspace}{false}
\begin{itemize}
\item \lipsum[5]
\end{itemize}
\end{document}
答案4
我的想法是不应该这样做,而是定义一个新的环境:
\newenvironment{itemizeplus}
{\begin{itemize}}
{\end{itemize}}
\AfterEndEnvironment{itemizeplus}{bleat bleat}
itemize
因此,和的行为itemizeplus
在整个文档中是可预测的。
注意。更有效的定义是
\let\itemizeplus\itemize
\let\enditemizeplus\enditemize
\AfterEndEnvironment{itemizeplus}{bleat bleat}
或者更好的是,
\let\itemizeplus\itemize
\def\enditemizeplus{\enditemize bleat bleat}