我正在尝试做类似的事情这问题。
我想在 a 的名称中使用计数器的值\hypertarget
,此外,我希望能够在\bookmark
a 内部引用这个名称\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
也不会造成任何影响,因此第二种方法通常更可取)。