# Evaluation order during macro expansion.

From this question Creating PDF bookmarks in custom order arose another. (I hope it is correct to create a new question instead of commenting or editing/answering my old question.)

Using this macro (after creating counter nops):

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


I want \nop to mark the current place and add a bookmark to it to the end of my bookmark list. what happens is that the correct number of bookmarks is created, but they all reference the last occurence of \nop. It seems that this is because the text within \BookmarkAtEnd is practically copied to the end instead of inserting the current values first. How can i change this?

-

\BookmarkAtEnd simply stores the token list given as its argument, but you need that \arabic{nops} is expanded before storing.

The more common trick is to say

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


The \begingroup and \endgroup are used just in order to avoid that \x has a definition after being used. We protect from expansion the commands \BookmarkAtEnd and \bookmark (\endgroup doesn't need to be protected because it's unexpandable); in this way the token list to be stored will contain the actual value of nops and not a command to get at its representation.

-
There is a } missing before \x, but otherwise it works! Thank you. –  peter Apr 30 '11 at 23:33
@peter: Oops, corrected. –  egreg Apr 30 '11 at 23:46