Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm trying to do something similar as in this question.

I would like to use the value of a counter in the name of a \hypertarget and in addition, I want to be able to refer to this name in a \bookmark inside a \BookmarkAtEnd.

Here is a MWE of what I'm trying to do:

\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}

The bookmarks show up alright but the problem is they both link to the last target. As can be seen from the output of the MWE, the problem is that everything inside \BookmarkAtEnd is not expanded until the end of the document.

Is there a way to make sure the calls to \target inside \BookmarkAtEnd are expanded right away?

share|improve this question
add comment

1 Answer 1

up vote 6 down vote accepted

You have to expand \target and \arabic{foo} when you use it to set the bookmark, otherwise \BookmarkAtEnd uses the last meaning of \target both for the text and the destination:

\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
}

When you call \foo, first of all we step the counter and this defines an anchor. Now, in a group (it is not required, but it's better), we define the meaning of \target and then we proceed to set the \hypertarget and the \bookmark using the current value of foo and of \target. So an expanded definition is necessary and it's accomplished with the \edef of \x; when \x is finally expanded, the \endgroup will annihilate its definition.

Note that if the expansion of \target contains commands such as \emph or \textbf, a slightly different approach must be taken:

\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

because \protected@edef is safe with commands that shouldn't be "completely expanded". If you're sure that the expansion of \target must contain only plain ASCII characters, then \edef can be used (but \protected@edef doesn't hurt either, so the second method is generally preferable).

share|improve this answer
    
Thanks a lot! That solved my problem. BTW, it is not necessary to add \hypertarget within \x because its arguments seem to be expanded in time. –  Job Mar 20 '12 at 16:45
    
I just have one more question about the grouping you use: would it make any difference if I put the \endgroup after the invocation of \x instead of inside its definition? –  Job Mar 20 '12 at 17:59
    
I don't know how \BookmarkAtEnd works; with this technique you're sure that this command is issued outside that group. –  egreg Mar 20 '12 at 20:36
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.