理解带标签的 \RemoveFromHook

理解带标签的 \RemoveFromHook

我意识到我的答案是这个问题关于删除的效果\tcolorboxenvironment并不理想,因为它会删除钩子和中的所有内容,env/<envname>/beforeenv/<envname>/after不仅仅是 tcolorbox 设置的代码。这是我的回答中的示例,它删除了添加到钩子中的所有代码:

\documentclass{article}
\usepackage[skins]{tcolorbox}

\newenvironment{myitemize}{\begin{itemize}}{\end{itemize}}

\tcolorboxenvironment{myitemize}{
    blanker, 
    before skip=6pt,
    after skip=6pt, 
    borderline west={3mm}{0pt}{red}
    }
                                 
\AddToHook{env/myitemize/after}{some code}

\newcommand{\untcolorboxenvironment}[1]{
    \RemoveFromHook{env/#1/before}
    \RemoveFromHook{env/#1/after}
    }
    
\begin{document}

\begin{myitemize}
\item text
\item more text
\end{myitemize}

\untcolorboxenvironment{myitemize}

\begin{myitemize}
\item text
\item more text
\end{myitemize}
\end{document}

坏的

可以想象这样一种情况,用户或其他包添加到这些钩子中,因此\untcolorboxenvironment应该只删除 tcolorbox 添加的代码。从 来看lthooks-doc,这段代码的标签似乎是,tcolorbox因为 中tcolorbox.sty没有给出标签,它应该默认为包名称。然而定义\untcolorboxenvironment

\newcommand{\untcolorboxenvironment}[1]{
    \RemoveFromHook{env/#1/before}[tcolorbox]
    \RemoveFromHook{env/#1/after}[tcolorbox]
    }

产生一个警告,指出此块对于此钩子不存在。删除 tcolorbox 添加的代码的正确方法是什么?

答案1

您无法删除tcolorbox标签,因为没有标签。使用\ShowHook{env/myitemize/after}会告诉您(请注意,“代码块”部分为空):

-> The generic hook 'env/myitemize/after':
> Code chunks:
>     ---
> Document-level (top-level) code (executed first):
>     -> \tcb@end@tcolorboxenvironment some code
> Extra code for next invocation:
>     ---
> Rules:
>     ---
> Execution order (after reversal):
>     ---.
<recently read> }

l.25 \ShowHook{env/myitemize/after}

?

相反,代码会随你的 一起tcolorbox添加到块中。发生这种情况是因为top-levelsome code\tcolorboxenvironment 在顶层执行,因此代码被添加到那里。

为了确保代码位于正确的标签中,您可以执行以下操作:

\PushDefaultHookLabel{tcolorbox}
  \tcolorboxenvironment{myitemize}{ ... }
\PopDefaultHookLabel

然后,添加到钩子上的所有代码都将被标记tcolorbox(除非明确说明)。执行此操作后,\ShowHook然后显示(请注意,“代码块”现在包含标签tcolorbox):

-> The generic hook 'env/myitemize/after':
> Code chunks:
>     tcolorbox -> \tcb@end@tcolorboxenvironment
> Document-level (top-level) code (executed first):
>     -> some code
> Extra code for next invocation:
>     ---
> Rules:
>     ---
> Execution order (after reversal):
>     tcolorbox.
<recently read> }

l.25 \ShowHook{env/myitemize/after}

?

另外,你会注意到top-level部分被引入为“ ”,因为这是一个反向钩子(钩子是反转的),所以代码在标有 的代码之前执行。Document-level (top-level) code (executed first)env/.../aftertop-leveltcolorbox

要反转执行顺序,您必须将顶层代码放在标签中,然后对它们进行排序,如下所示:

\AddToHook{env/myitemize/after}[mycode]{some code}
\DeclareHookRule{env/myitemize/after}{mycode}{after}{tcolorbox}

然后,\ShowHook会告诉您想要的执行顺序:

-> The generic hook 'env/myitemize/after':
> Code chunks:
>     tcolorbox -> \tcb@end@tcolorboxenvironment
>     mycode -> some code
> Document-level (top-level) code (executed first):
>     ---
> Extra code for next invocation:
>     ---
> Rules:
>     tcolorbox|mycode with relation <
> Execution order (after reversal and applying rules):
>     tcolorbox, mycode.
<recently read> }

l.26 \ShowHook{env/myitemize/after}

?

梅威瑟:

\documentclass{article}
\usepackage[skins]{tcolorbox}

\newenvironment{myitemize}{\begin{itemize}}{\end{itemize}}

\PushDefaultHookLabel{tcolorbox}
\tcolorboxenvironment{myitemize}{
    blanker, 
    before skip=6pt,
    after skip=6pt, 
    borderline west={3mm}{0pt}{red}
    }
\PopDefaultHookLabel

\AddToHook{env/myitemize/after}[mycode]{some code}
\DeclareHookRule{env/myitemize/after}{mycode}{after}{tcolorbox}

\newcommand{\untcolorboxenvironment}[1]{%
    \RemoveFromHook{env/#1/before}[tcolorbox]%
    \RemoveFromHook{env/#1/after}[tcolorbox]%
    }

\begin{document}

\ShowHook{env/myitemize/after}

\begin{myitemize}
\item text
\item more text
\end{myitemize}

\untcolorboxenvironment{myitemize}

\begin{myitemize}
\item text
\item more text
\end{myitemize}
\end{document}

相关内容