宏扩展期间的评估顺序。

宏扩展期间的评估顺序。

从这个问题按自定义顺序创建 PDF 书签又出现了另一个。(我希望创建新问题而不是评论或编辑/回答我的旧问题是正确的。)

使用此宏(创建计数器之后nops):

\newcommand{\nop}{
  \stepcounter{nops}\hypertarget{nop\arabic{nops}}{}
  \BookmarkAtEnd{
    \bookmark[dest=nop\arabic{nops}]{page \arabic{nops}}
  }
}

我想\nop标记当前位置并在书签列表末尾添加书签。发生的情况是创建了正确数量的书签,但它们都引用了最后一次出现的\nop。这似乎是因为其中的文本\BookmarkAtEnd实际上被复制到末尾,而不是先插入当前值。我该如何改变这种情况?

答案1

\BookmarkAtEnd只是将给出的标记列表存储为其参数,但是您需要\arabic{nops}在存储之前对其进行扩展。

更常见的伎俩是说

\newcommand{\nop}{%
  \stepcounter{nops}\hypertarget{nop\arabic{nops}}{}%
  \begingroup\edef\x{\endgroup\noexpand\BookmarkAtEnd{%
    \noexpand\bookmark[dest=nop\arabic{nops}]{page \arabic{nops}}}}\x
}

使用\begingroup\endgroup只是为了避免\x使用后有定义。我们保护命令\BookmarkAtEnd和不被扩展\bookmark\endgroup不需要保护,因为它是不可扩展的);这样,要存储的标记列表将包含和的实际值,nops而不是获取其表示的命令。

更新

利用最新的 TeX 发行版,您可以利用expl3并获得抽象,然后将其用于其他计数器。

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\nop}{}
 {
  \peter_bookmark:nne { nop } { nops } { \arabic{nops} }
 }
\cs_new_protected:Nn \peter_bookmark:nnn
 {
  \stepcounter{#2}
  \hypertarget{#1#3}{}
  \BookmarkAtEnd{\bookmark[dest=#1#3]{page~#3}}
 }
\cs_generate_variant:Nn \peter_bookmark:nnn { nne }
\ExplSyntaxOff

这个想法是在扩展之前先扩展第三个参数\peter_bookmark:nnn,它是通过使用e变体获得的。

相关内容