Ich sehe die folgenden Fehlermeldungen von pdflatex bei einem wirklich riesigen Projekt:
(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
Der Anfang meiner Hauptdatei sieht folgendermaßen aus:
\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...
Ein Beispiel \codeblock
aus dem Haupttext:
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}...
Und ein Beispiel für \codeblockref
:
Compare this version of the code to the version on page
\codeblockref{1}{1}.
Leider funktioniert es einwandfrei, wenn Sie nur diese Schnipsel in einer Testdatei zusammenstellen und ausführen pdflatex test.tex; pdflatex test.tex
! (Außer, dass der Hyperlink bei der Nummer „1“ tatsächlich zum Inhaltsverzeichnis und nicht zu Seite 1 führt.) Aber wenn ich dasselbe im Maßstab mehrerer Kapitel mache, erhalte ich die Fehlermeldungen, die lstnumber.-14.11
oben in dieser Frage zu sehen sind.
Ich habe herausgefunden, dass dies lstnumber.-<some number>
das Format der vom listings
Paket automatisch generierten Etiketten ist. Daher gehe ich davon aus, dass es sich um eine fehlerhafte Interaktion zwischen listings
und hyperref
handelt. Aber was genau läuft schief und was kann ich tun, um es zu beheben?
Das \hspace{1em}
in meinem \codeblock
Makro war mein naiver Versuch, den beschriebenen Fehler zu umgehenHier, falls das das Problem war.
Antwort1
Hier ist ein Beispiel, wie es meiner Meinung nach gemacht werden sollte:
Der Befehl wird angewendet, bevor das Makro verwendet wird, also bevor der Zähler erhöht wurde, um eine Referenzierung mit zu ermöglichen \codeblock
– die Verwendung von „before“ ist ein sehr häufiger Fehler und daher werden die von geschriebenen Querverweisinformationen von einem potenziellen „before“ verwendet , das in Verbindung mit einem usw. Zähler stehen könnte , sodass die Informationen falsch sind und die Hyperanker-Koordinaten von einer älteren Ankerinstanz „before“ übernommen werden. Auf diese Weise verweisen die Links auf eine falsche Position zurück.\label
\lstinputlisting
listings
\refstepcounter
\label
\refstepcounter
\label
\refstepcounter
section
Tatsächlich \lstinputlisting
besteht die label=
Möglichkeit, den Etikettennamen anzugeben.
Das Folgende ist eine sehr reduzierte Form, die von Nicht-MWE bereitgestellt wird, aber funktioniert.
\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}
Antwort2
Beim Posten dieser Frage bin ich über die Antwort gestolpert! (Nicht, dass ich es verstehe.WarumEs klappt...)
Wenn Sie nur diese Schnipsel in einer Testdatei zusammenstellen und ausführen,
pdflatex test.tex; pdflatex test.tex
funktioniert es einwandfrei! (Außer, dass der Hyperlink bei der Nummer „1“ tatsächlich zum Inhaltsverzeichnis und nicht zu Seite 1 führt.)
Als Fehler auftraten, war ich nicht überrascht, dass der Hyperref an die falsche Stelle ging. Beim reduzierten Testfall war ich jedoch verwirrt. Also las ich überDasProblem, und fand heraus, dass das, was ich wollte \phantomsection
, so war:
\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}}
Beachten Sie, dass mein Cargo-Kult \hspace{1em}
(soweit ich weiß) nicht mehr benötigt wird und ich die Sonderzeichen, die ich beim Versuch, den Testfall zu reduzieren, lst:#1-#2
durch ersetzt hatte, wieder einfügen konnte.foo#1#2
...Und wie durch Zauberei wird mein riesiges Projekt plötzlich einwandfrei kompiliert! Keine mysteriösen Fehlermeldungen mehr. Alle Hyperref-Links führen zu den richtigen Seiten und zeigen den richtigen Textkörper an.
Ich habe keine Ahnung, warum das Weglassen \phantomsection
solches Chaos verursacht hat, aber nachdem ich es eingefügt habe, war alles behoben!