\refstepcounter{enumi} 两次(或更多)创建“具有相同标识符的目的地”

\refstepcounter{enumi} 两次(或更多)创建“具有相同标识符的目的地”

我不明白下面的 MWE 如何产生这样的警告:

{c:/.../texlive/texmf-var/fonts/map/pdftex/updmap/pdftex.map}pdfTeX warning (ext4): desti
nation with the same identifier (name{enumi.1}) has been already used, duplicate ignored

(这种特殊的格式可以防止警告被某些自动解析程序(例如 TeXstudio 中的程序)接收,因此如果这是一个被遗漏的错误,我不会感到惊讶。)

\refstepcounter{enumi}如果我用 替换每个,则不会出现相同的警告\item

这是我的 MWE:

\documentclass{article}
\usepackage{hyperref}

\begin{document}
    \begin{enumerate}
        \item \label{crit:1} This shall be 1
    \end{enumerate}

    Something else.

    \begin{enumerate}
        \refstepcounter{enumi}%
        \refstepcounter{enumi}%
        \item \label{crit:3} This shall be 3
    \end{enumerate} 

    Also, this (\ref{crit:3}) shall be 3, which is why this (\ref{crit:3b}) does not work:

    \begin{enumerate}
        \item[3.] \label{crit:3b} This shall be 3
    \end{enumerate}

\end{document}

考虑了@HeikoOberdiek 的回答后,这是我将他的修复应用于更一般情况的扩展 MWE。只需取消注释重新定义即可\fixWarning看到效果。

\documentclass{article}
\usepackage{hyperref}
\newcommand{\fixWarning}{}
\makeatletter
%\renewcommand{\fixWarning}{\@hyper@itemfalse\if@nmbrlist\@hyper@itemtrue\fi}
\makeatother
\begin{document}
    \begin{enumerate}
        \refstepcounter{enumi}
        \fixWarning % the first one removes two warnings
        \refstepcounter{enumi}
        \fixWarning % each subsequent one removes a warning each
        \refstepcounter{enumi}
        \fixWarning
        \refstepcounter{enumi}
        \fixWarning
        \refstepcounter{enumi}
        \fixWarning
        \refstepcounter{enumi}
        \fixWarning
        \refstepcounter{enumi}
        \fixWarning
        \refstepcounter{enumi}
        %\fixWarning % not needed!
        \refstepcounter{enumi}
        \item This shall be 10.
    \end{enumerate}

    With \verb|\fixWarning| empty, we receive 8 warnings in the log file.
\end{document}

我想知道hyperref将来是否应该包含这个修复。

答案1

软件包hyperref补丁\item

\let\H@item\item
\def\item{%
  \@hyper@itemfalse
  \if@nmbrlist\@hyper@itemtrue\fi
  \H@item
}

自从,\refstepcounter被使用第一种\item,插入的补丁代码需要手动添加:

\begin{enumerate}
    \makeatletter
    \@hyper@itemfalse
    \if@nmbrlist\@hyper@itemtrue\fi
    \makeatother
    \refstepcounter{enumi}%
    \refstepcounter{enumi}%
    \item \label{crit:3} This shall be 3
\end{enumerate}

第二种情况带有可选参数

\begin{enumerate}
    \item[3.] \label{crit:3b} This shall be 3
\end{enumerate}

不是完全支持。问题之一:从哪个数字中得出\item[foobar]

答案2

Heiko Oberdiek 已经解释了修补的\item命令。

\refstepcounter我建议使用提供的环境start=选项,而不是使用。请注意 会按原样使用起始编号值,即无需先减少编号,这将导致以 开始。enumerateenumitemenumitemstart=3enumerate3

对于缺少的引用\item[...]-- 没有\refstepcounter使用,因此未\@currentlabel设置。这可以通过一个名为 say 的简单宏来解决,\fakelabel该宏显示标签并存储与 相同的内容\@currentlabel

\documentclass{article}
\usepackage{enumitem}
\usepackage{hyperref}

\makeatletter
\newcommand{\fakelabel}[1]{#1\protected@edef\@currentlabel{#1}}
\makeatother

\begin{document}
    \begin{enumerate}
        \item \label{crit:1} This shall be 1
    \end{enumerate}

    Something else.

    \begin{enumerate}[start=3]
    \item \label{crit:3} This shall be 3
    \end{enumerate} 

    Also, this (\ref{crit:3}) shall be 3, which is why this (\ref{crit:3b}) does not work:

    \begin{enumerate}[start=3]
    \item[\fakelabel{foobar} \label{crit:3b}] This shall be foobar!
    \end{enumerate}

\end{document}

在此处输入图片描述

相关内容