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 created a small example:

\documentclass[a4paper,12pt]{article}
\usepackage{amsmath}
\usepackage[pdfstartview=FitH]{hyperref}
\usepackage{bookmark}
\begin{document}
one line
\newcounter{test}
\[\text{\stepcounter{test}\bookmark[dest=whatever]{my equation}one equation}\]
counter value: \arabic{test}.
\end{document}

It creates 4 bookmarks but increases the counter only by 1. How is that (even logically) possible? Either this equation environment somehow executes the code 4 times (maybe first measuring the contents or whatever), then the counter should be increased by four. Or it only executes once, then there should only be one bookmark.

How do I get it to display only one bookmark? (moving it out of the equation is not an option since this happens inside a macro which at the same time marks the equation as target.)

update:

alright, egregs \tbookmark command fixed my minimal example. turns out it was too minimal. here is another one which went back to not working:

\documentclass[a4paper,12pt]{article}
\usepackage{amsmath}
\usepackage[pdfstartview=FitH]{hyperref}
\usepackage[atend]{bookmark}
\makeatletter\newcommand{\tbookmark}[2][]{\iffirstchoice@\bookmark[#1]{#2}\fi}\makeatother
\newcounter{nops}
\newcommand{\nop}{\stepcounter{nops}\raisebox{\ht\strutbox}{\hypertarget{nop\arabic{nops}}{}}\begingroup\edef\x{\endgroup\noexpand\BookmarkAtEnd{\noexpand\tbookmark[dest=nop\arabic{nops}]{page \arabic{nops}}}}\x}
\begin{document}
one line
\[\text{\nop one equation}\]
counter value: \arabic{nops}.
\end{document}
share|improve this question
    
I get only one bookmark. (I use TeX Live 2010 with latest packages) –  Leo Liu May 1 '11 at 15:14
    
I use miktex 2.9. I just started an update and will report back later. What additional information might be helpful to debug this? –  peter May 1 '11 at 15:18
3  
the TeX primitive \mathchoice has four arguments corresponding to display, text, script and script-script style. When TeX encounters it it constructs all four and then inserts the appropriate one. So it could be a case of this primitive being used somewhere. –  jfbu May 1 '11 at 17:37
    
updated miktex, output unchanged. –  peter May 1 '11 at 20:56

1 Answer 1

up vote 6 down vote accepted

\text uses internally \mathchoice (so jfbu was right), but amstext.sty redefines \stepcounter and \addtocounter in such a way that they act only once.

A cheap solution would be to define a special \bookmark command:

\makeatletter
\newcommand{\tbookmark}[2][]{%
  \iffirstchoice@
    \bookmark[#1]{#2}%
  \fi}
\makeatother

that will be free of the problem. Probably something that Heiko should take care of.

One might try also with letltxmacro (the redefinition must go after \usepackage{bookmark}):

\usepackage{letltxmacro}
\makeatletter
\LetLtxMacro{\orig@bookmark}{\bookmark}
\renewcommand{\bookmark}[2][]{%
  \iffirstchoice@\orig@bookmark[#1]{#2}\fi}
\makeatother

--- Added after Peter's edits ---

Any command to be used inside \text and which sets bookmarks or hypertargets should be defined in terms of \iffirstchoice@:

\newcommand{\nop}{%
  \stepcounter{nops}%
  \iffirstchoice@
    \raisebox{\ht\strutbox}{\hypertarget{nop\arabic{nops}}{}}
  \fi}

The AMS packages define \text using the conditional \iffirstchoice@; essentially, \text{...} is defined to become

\mathchoice{\firstchoice@true\textrm{...}}
           {\firstchoice@false\textrm{...}}
           {\firstchoice@false\textrm{...}}
           {\firstchoice@false\textrm{...}}

One has to remember that \mathchoice typesets all four forms and TeX chooses one depending on the needed math style; with \iffirstchoice@<tokens>\fi we are sure that the <tokens> are found only once.

share|improve this answer
    
How is \LetltxMacro different from \let? –  Aditya May 1 '11 at 20:27
    
@Aditya: When a command is defined with an optional argument, using \let to keep its definition is not safe at all. I believe this is a good question to ask. –  egreg May 1 '11 at 21:04
    
@egreg: Thanks. I looked up the documentation of letltxmacro and it clearly explains why \let fails. –  Aditya May 1 '11 at 21:59
    
@egreg: thank you. how exactly does \iffirstchoice work? It's damn hard to google the things I get suggested here. ;-) I dont understand why the LetltxMacro package is needed in the second example. can't I just use a \renewcommand instead of the \newcommand? –  peter May 3 '11 at 6:33
    
you fixed my minimal example, but my production file still exhibited the faulty behavior. so please look at the new minimal example, i updated the question. –  peter May 3 '11 at 6:58

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.