我如何撤消 etoolbox 补丁?

我如何撤消 etoolbox 补丁?

假设我使用电子工具箱命令如\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}

相关内容