リストとハイパー参照の競合: 「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前、つまり、で参照できるようにカウンターが増加する前に適用されます。以前を使用することは非常に一般的なエラーであり、 によって書き込まれた相互参照情報は、 などのカウンターと組み合わせて使用​​される可能性のある、以前に使用された可能性のあるものから使用されるため、情報が間違っており、ハイパー アンカー座標は以前の古いアンカー インスタンスから取得されます。このように、リンクは間違った位置を指します。\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 ではなく目次に移動します。)

エラーが出たときは、ハイパーリファレンスが間違った場所に行くことに驚きませんでした。しかし、テストケースが縮小されたので、困惑しました。そこで、それ問題を解決し、私が求めていたのは\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 はもう必要ないことに注目してください(AFAIK)。また、テスト ケースを削減しようとしたときに置き換えた\hspace{1em}特殊文字を元に戻せました。lst:#1-#2foo#1#2

...そして魔法のように、突然、私の巨大なプロジェクトが正常にコンパイルされるようになりました。不可解なエラー メッセージはもう表示されません。すべてのハイパー参照リンクが正しいページに移動し、正しい本文​​テキストが表示されます。

省略するとなぜこのような混乱が生じるのかわかりません\phantomsectionが、挿入するとすべてが修正されました。

関連情報