方程环境中的代码执行了 4 次(或者不是吗?)。

方程环境中的代码执行了 4 次(或者不是吗?)。

我创建了一个小例子:

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

它创建了 4 个书签,但计数器只增加了 1。这怎么可能(甚至在逻辑上)?要么这个方程环境以某种方式执行了代码 4 次(可能首先测量内容或其他),然后计数器应该增加 4。或者它只执行一次,那么应该只有一个书签。

我如何让它只显示一个书签?(将它移出等式不是一个选择,因为这发生在宏内部,同时将等式标记为目标。)

更新

好吧,egregs\tbookmark命令修复了我的最小示例。结果发现它太小了。这里是另一个无法正常工作的示例:

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

答案1

\text内部使用\mathchoice(因此 jfbu 是正确的),但amstext.sty重新定义\stepcounter并且\addtocounter以使它们只作用一次。

一个廉价的解决方案是定义一个特殊的\bookmark命令:

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

这样就不会有问题了。这或许是 Heiko 应该处理的事情。

也可以尝试letltxmacro(重新定义必须在之后进行\usepackage{bookmark}):

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

--- 在 Peter 编辑后添加 ---

任何在内部使用\text并设置书签或超目标的命令都应根据以下内容定义\iffirstchoice@

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

AMS 包\text使用条件定义\iffirstchoice@;本质上,\text{...}定义为

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

必须记住,\mathchoice排版所有四种形式,并且 TeX 根据所需的数学样式选择其中一种;\iffirstchoice@<tokens>\fi我们确信它们<tokens>只会被找到一次。

相关内容