목록과 하이퍼참조 간의 충돌: "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-- before \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}}

내 화물 숭배는 \hspace{1em}더 이상 필요하지 않습니다(AFAIK). 그리고 테스트 케이스를 줄이려고 할 때 lst:#1-#2대체했던 특수 문자를 다시 넣을 수 있었습니다 .foo#1#2

...그리고 마술처럼 갑자기 내 거대한 프로젝트가 잘 컴파일됩니다! 더 이상 신비한 오류 메시지가 없습니다. 모든 하이퍼참조 링크는 올바른 페이지로 이동하고 올바른 본문 텍스트를 표시합니다.

생략하면 왜 이렇게 큰 혼란이 일어나는지 모르겠지만 \phantomsection, 입력하고 나면 모든 것이 해결됩니다!

관련 정보