如何在 \BookmarkAtEnd 内的 \bookmark 目标名称中使用计数器?

如何在 \BookmarkAtEnd 内的 \bookmark 目标名称中使用计数器?

我正在尝试做类似的事情问题。

我想在 a 的名称中使用计数器的值\hypertarget,此外,我希望能够在\bookmarka 内部引用这个名称\BookmarkAtEnd

以下是我正在尝试做的 MWE:

\documentclass{article}
\usepackage{hyperref}
\usepackage[atend]{bookmark}
\BookmarkAtEnd{\bookmark[level=0,named=LastPage]{Foos}}
\newcounter{foo}
\newcommand{\foo}{
  \refstepcounter{foo}
  \def\target{foo\arabic{foo}}
  \hypertarget{\target}{Foo: \target}
  \BookmarkAtEnd{\bookmark[level=1,dest=\target]{\target}}
}
\begin{document}
\foo

\foo
\end{document}

书签显示正常,但问题是它们都链接到最后一个目标。从 MWE 的输出可以看出,问题是里面的所有内容\BookmarkAtEnd直到文档末尾才展开。

\target有没有办法确保内部调用\BookmarkAtEnd立即扩展?

答案1

您必须展开它\target\arabic{foo}使用它设置书签,否则将使用文本和目标\BookmarkAtEnd的最后含义:\target

\newcounter{foo}
\newcommand{\foo}{%
  \refstepcounter{foo}%
  \begingroup
  \def\target{foo\arabic{foo}}%
  \edef\x{\endgroup
  \noexpand\hypertarget{\target}{Foo: \target}%
  \noexpand\BookmarkAtEnd{\noexpand\bookmark[level=1,dest=\target]{\target}}}\x
}

当您调用 时\foo,首先我们踩下计数器,这定义了一个锚点。现在,在一个组中(这不是必需的,但最好),我们定义 的含义,\target然后我们继续使用来设置\hypertarget\bookmark当前的的值foo和 的值\target。因此,扩展定义是必要的,它是通过 的来实现的\edef\x\x最终扩展时,\endgroup将消灭其定义。

请注意,如果的扩展\target包含诸如\emph或之类的命令\textbf,则必须采取略有不同的方法:

\makeatletter
\newcommand{\foo}{%
  \refstepcounter{foo}%
  \begingroup
  \def\target{foo\arabic{foo}}%
  \protected@edef\x{\endgroup
  \noexpand\hypertarget{\target}{Foo: \target}%
  \noexpand\BookmarkAtEnd{\noexpand\bookmark[level=1,dest=\target]{\target}}}\x
}
\makeatother

因为\protected@edef对于不应“完全展开”的命令而言是安全的。如果您确定的展开\target必须只包含纯 ASCII 字符,则\edef可以使用(但\protected@edef也不会造成任何影响,因此第二种方法通常更可取)。

相关内容