如何重置/清除钩子(或:如何仅打印一次背景图片)

如何重置/清除钩子(或:如何仅打印一次背景图片)

我想在单页背景中添加图片,但如果我使用\AddToHook它,它会出现在文档的每一页上。如果我想在它出现在特定页面(因此只有一页)后清除它,我该怎么做?我以为\ClearHookNext可以,但我得到了Undefined control sequence(macOS 12.1,最新的 TeXLive 2021)。

\documentclass{scrartcl}
\usepackage{tikz}
\usepackage{blindtext}
\begin{document}
\blindtext[10]
\AddToHook{shipout/background}{\put(0,0){%
\begin{tikzpicture}[remember picture, overlay, shift={(current page.center)}]
   \draw[fill, color=red] (0,0) circle (2cm);
\end{tikzpicture}%
}}
\blindtext[10]
% Trials:
% \RemoveFromHook{shipout/background}% removes all (so also the first one we wanted to print)
%\ClearHookNext{shipout/background}% Undefined control sequence
\end{document}

更新:另一个不同但相关的问题是,如何在几页之后关闭挂钩(当您事先不知道确切的页码时,因为内容的长度是可变的)。此时使用根本不会绘制背景图片(尽管人们希望它在和命令\RemoveFromHook之间绘制它们):\AddToHook\RemoveFromHook

\documentclass{scrartcl}
\usepackage{tikz}
\usepackage{blindtext}
\begin{document}
\blindtext[10]
\AddToHook{shipout/background}{\put(0,0){%
\begin{tikzpicture}[remember picture, overlay, shift={(current page.center)}]
   \draw[fill, color=red] (0,0) circle (2cm);
\end{tikzpicture}%
}}
\blindtext[10]
\RemoveFromHook{shipout/background}
\blindtext[10]
\end{document}

答案1

您可以使用\AddToHookNext{<hook>}它添加仅在下次调用时执行的代码<hook>。下面的文档打印了 5 页,第三页中间有一个红色圆圈:

\documentclass{scrartcl}
\usepackage{tikz}
\usepackage{blindtext}
\begin{document}
\blindtext[10] % blank line below required

\AddToHookNext{shipout/background}{\put(0,0){%
\begin{tikzpicture}[remember picture, overlay, shift={(current page.center)}]
   \draw[fill, color=red] (0,0) circle (2cm);
\end{tikzpicture}%
}}
\blindtext[10]
\end{document}

第一个和之间的空白行\blindtext\AddToHookNext必需的,这样 TeX 才能进行处理\blindtext[10](将其分成段落,再将段落分成页面,从而将页面发送出去),然后当您调用时,\AddToHookNext您就会在正确的页面上。如果您不添加空白行,那么在您调用时,\AddToHookNextTeX 仍在处理第一页(即使它有两页完整的内容存储在内存中),因此圆圈最终会出现在错误的位置。


另一种方法是,如果您想将圆圈放在特定的页面(而不是“就在这里”),可以测试页码:

\documentclass{scrartcl}
\usepackage{tikz}
\usepackage{blindtext}
\begin{document}
\blindtext[10]
\AddToHook{shipout/background}{%
  \ifnum\value{page}=3 % only on page 3
    \put(0,0){%
    \begin{tikzpicture}[remember picture, overlay, shift={(current page.center)}]
       \draw[fill, color=red] (0,0) circle (2cm);
    \end{tikzpicture}%
    }%
  \fi}
\blindtext[10]
\end{document}

如果您想在文档中间的钩子中打开和关闭代码(页码未知),那么您需要规则提供的更细粒度的控制。

如下例所示,您可以将圆圈代码标记为./mycircle,并添加另一个标记为 的空白代码块./stop-mycircle。默认情况下,添加的两个代码块都会执行(第二个代码块为空白,因此不会造成任何损害)。然后,当您想要停用圆圈背景时,您可以这样写

\DeclareHookRule{shipout/background}{./stop-mycircle}{voids}{./mycircle}

这样./stop-mycircle钩子中的 就不会./mycircle执行了。然后你可以写

\ClearHookRule{shipout/background}{./mycircle}{./stop-mycircle}

删除该“ voids”规则并允许./mycircle再次执行。

这种方法的最大优点是您可以随意打开或关闭这些命令:这些命令不会对您添加到钩子中的代码产生破坏性影响,因此您可以随时恢复。事实上,\RemoveFromHook在大多数情况下,最好用 代替voids

以下是代码(其输出仅包含第 3、4 和 5 页的圆圈):

\documentclass{scrartcl}
\usepackage{tikz}

\AddToHook{shipout/background}[./mycircle]{\put(0,0){%
  \begin{tikzpicture}[remember picture, overlay, shift={(current page.center)}]
    \draw[fill, color=red] (0,0) circle (2cm);
  \end{tikzpicture}}}
\AddToHook{shipout/background}[./stop-mycircle]{}
\newcommand\circleon{%
  \ClearHookRule{shipout/background}{./mycircle}{./stop-mycircle}}
\newcommand\circleoff{%
  \DeclareHookRule{shipout/background}{./stop-mycircle}{voids}{./mycircle}}
\circleoff % initially off

\begin{document}
page 1 \clearpage
page 2 \clearpage
page 3 \circleon \clearpage % start showing on page 3
page 4 \clearpage
page 5 \clearpage
page 6 \circleoff \clearpage % no longer show on page 6
page 7 \clearpage
\end{document}

\ClearHookNext不应读作“在下次执行后清除钩子”,而应读作“清除‘下次执行’代码”,因此它会删除添加的代码\AddToHookNext。要删除添加的代码,\AddToHook您必须使用或添加另一个代码标签,并添加要删除\RemoveFromHook的规则。voids

相关内容