列表和超链接之间存在冲突:“lstnumber.-14.11”被引用但不存在

列表和超链接之间存在冲突:“lstnumber.-14.11”被引用但不存在

我在一个非常庞大的项目中看到了来自 pdflatex 的以下错误消息:

(see the transcript file for additional information)pdfTeX warning (dest): name
{lstnumber.-14.11} has been referenced but does not exist, replaced by a fixed 
one

pdfTeX warning (dest): name{lstnumber.-18.22} has been referenced but does not 
exist, replaced by a fixed one

pdfTeX warning (dest): name{lstnumber.-9.40} has been referenced but does not e
xist, replaced by a fixed one

pdfTeX warning (dest): name{lstnumber.-4.3} has been referenced but does not ex
ist, replaced by a fixed one

我的主文件顶部如下所示:

\documentclass[ebook,10pt,oneside,final]{memoir}
\usepackage{microtype}

% support for code listings
\usepackage[final]{listings}
\include{autodedent}
\lstset{
  basicstyle=\ttfamily\footnotesize,
  numberstyle=\footnotesize,
  breaklines=true,
  numbers=left,
  firstnumber=1,
  rangeprefix=//,
  includerangemarker=false
}

% support for indexing
\usepackage{makeidx}
\makeindex

% make _ a non-special character
\usepackage{underscore}

% support for cross-references
\usepackage{hyperref}
% \newcommand{\href}[2]{#2}

% fix spacing in \tableofcontents
\renewcommand\partnumberline[1]{#1\hspace{1em}}

% custom commands for use in the text of the book itself
\newcommand{\newterm}[1]{\textit{#1}}
\newcommand{\code}[1]{\mbox{\lstinline[basicstyle=\ttfamily]$#1$}}
\newcommand{\slurl}[1]{\href{https://#1}{\textsl{#1}}}
\newcommand{\codeblock}[2]{\label{foo#1#2}\hspace{1em}\lstinputlisting[linerange=ex#2-dex#2,autodedent]{examples-ch#1.cc}}
\newcommand{\codeblockref}[2]{\pageref{foo#1#2}}
\newcommand{\Csharp}{C\#}

\begin{document}

\frontmatter
\include{preface}
\tableofcontents

\mainmatter

% ...and so on...

\codeblock来自正文的一个例子:

Let's write a function to multiply each of the elements
in an array by 2.

\codeblock{1}{1}

Our function \code{double_each_element} works \emph{only} with objects of type
\code{array_of_int}...

例如\codeblockref

Compare this version of the code to the version on page
\codeblockref{1}{1}.

不幸的是,如果你把这些代码片段放在一个测试文件中并运行pdflatex test.tex; pdflatex test.tex— 它会运行良好!(除了数字“1”上的超链接实际上指向目录,而不是第 1 页。)但是当我在多章的规模上做同样的事情时,我得到了关于lstnumber.-14.11此问题顶部所见的错误消息。

我确实发现这lstnumber.-<some number>是由包自动生成的标签的格式,因此我认为这是和listings之间的一些不良交互。但究竟出了什么问题,我该怎么做才能解决它?listingshyperref


\hspace{1em}我的宏\codeblock是我天真的尝试解决所描述的错误这里,以防这是问题所在。

答案1

以下是我认为应该如何做的示例:

\codeblock命令\label应用之前\lstinputlisting,即在listings计数器增加以允许引用之前\refstepcounter——使用\label之前\refstepcounter是一个非常常见的错误,因此,写入的交叉引用信息\label来自\refstepcounter之前使用的潜在信息,该信息可能与等计数器结合使用section,因此信息是错误的,并且超锚点坐标取自之前较旧的锚点实例。这样,链接指向错误的位置。

事实上,\lstinputlisting有一个label=指定标签名称的选项。

以下是非 MWE 给出的非常简化的形式,但有效。

\documentclass[ebook,10pt,oneside,final]{memoir}
\usepackage{microtype}

% support for code listings

\begin{filecontents}{examplehelloworld.c}
#include<stdio.h>

int main(int argc,char **argv)
{
  printf("Hello World!\n");
  return(0);
}
\end{filecontents}

\usepackage[final]{listings}
%\include{autodedent}
\lstset{
  basicstyle=\ttfamily\footnotesize,
  numberstyle=\footnotesize,
  breaklines=true,
  numbers=left,
  firstnumber=1,
  rangeprefix=//,
  includerangemarker=false
}

% support for indexing
\usepackage{makeidx}
\makeindex

% make _ a non-special character
\usepackage{underscore}

% support for cross-references
\usepackage{hyperref}
% \newcommand{\href}[2]{#2}

% fix spacing in \tableofcontents
\renewcommand\partnumberline[1]{#1\hspace{1em}}

% custom commands for use in the text of the book itself
\newcommand{\newterm}[1]{\textit{#1}}
\newcommand{\code}[1]{\mbox{\lstinline[basicstyle=\ttfamily]$#1$}}
\newcommand{\slurl}[1]{\href{https://#1}{\textsl{#1}}}
\newcommand{\codeblock}[2]{\hspace{1em}\lstinputlisting[language={C},label={lst:#1-#2}]{examplehelloworld.c}}
\newcommand{\codeblockref}[2]{\pageref{lst:#1-#2}}
\newcommand{\Csharp}{C\#}


\usepackage{blindtext}

\begin{document}

\frontmatter
%\include{preface}
\tableofcontents

\mainmatter


\blindtext[3]


Reference: \codeblockref{1}{4}

\blindtext[5]


\codeblock{1}{4}



\end{document}

答案2

在发布这个问题的过程中,我偶然发现了答案!(虽然我不明白为什么有用...)

如果您将这些代码片段放在一个测试文件中并运行pdflatex test.tex; pdflatex test.tex— 它会运行良好!(除了数字“1”上的超链接实际上指向目录,而不是第 1 页。)

当它抛出错误时,我并不惊讶于超链接指向了错误的地方。然而,由于测试用例减少,我感到很困惑。所以我去阅读了问题,发现我想要的是\phantomsection,像这样:

\newcommand{\codeblock}[2]{\phantomsection\label{lst:#1-#2}\lstinputlisting[linerange=ex#2-dex#2,autodedent]{examples-ch#1.cc}}
\newcommand{\codeblockref}[2]{\pageref{lst:#1-#2}}

请注意,我的 cargo-cult\hspace{1em}不再需要(据我所知);并且我能够放回lst:#1-#2我在foo#1#2尝试减少测试用例时替换的特殊字符。

...神奇的是,我的大型项目突然编译成功了!不再有神秘的错误消息。所有超链接都转到正确的页面,并显示正确的正文。

我不知道为什么省略\phantomsection会造成如此大的破坏,但放进去之后,一切都解决了!

相关内容