列表和 hyperref 之間存在衝突:引用了“lstnumber.-14.11”,但不存在

列表和 hyperref 之間存在衝突:引用了“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\lstinputlistinglistings\refstepcounter\label\refstepcounter\label\refstepcountersection

事實上,\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 頁。)

當它拋出錯誤時,我對 hyperref 去到錯誤的地方並不感到驚訝。然而,隨著測試案例的減少,我感到困惑。所以我去讀了問題,發現我想要的是\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}}

請注意,我的貨物崇拜\hspace{1em}不再需要了(據我所知);我能夠放回嘗試減少測試案例時lst:#1-#2替換的特殊字元。foo#1#2

……神奇的是,我的龐大專案突然編譯得很好!不再有神秘的錯誤訊息。所有超引用連結都會轉到正確的頁面,並顯示正確的正文文字。

我不知道為什麼省略\phantomsection會造成如此嚴重的破壞,但是在添加它之後,一切都解決了!

相關內容