Veo los siguientes mensajes de error de pdflatex en un proyecto realmente gigantesco:
(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
La parte superior de mi archivo principal se ve así:
\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...
Un ejemplo del \codeblock
cuerpo del texto:
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}...
Y un ejemplo de \codeblockref
:
Compare this version of the code to the version on page
\codeblockref{1}{1}.
Desafortunadamente, si junta solo estos fragmentos en un archivo de prueba y los ejecuta, pdflatex test.tex; pdflatex test.tex
¡funcionará bien! (Excepto que el hipervínculo en el número "1" en realidad va a la tabla de contenido, no a la página 1.) Pero cuando hago lo mismo en la escala de muchos capítulos, aparece el mensaje de error que se lstnumber.-14.11
ve en la parte superior de esta pregunta.
Descubrí que ese lstnumber.-<some number>
es el formato de las etiquetas que el paquete genera automáticamente listings
, así que supongo que se trata de una mala interacción entre listings
y hyperref
. Pero, ¿qué es exactamente lo que está fallando y qué puedo hacer para solucionarlo?
Lo \hspace{1em}
de mi \codeblock
macro fue mi ingenuo intento de solucionar el error descrito.aquí, en caso de que ese fuera el problema.
Respuesta1
Aquí está el ejemplo de cómo se debe hacer, en mi opinión:
El comando se aplica antes de que se use la macro, es decir, antes de que se haya aumentado el \codeblock
contador para permitir la referencia. Usar antes es un error muy común y, como tal, la información de referencia cruzada escrita por se usa desde un potencial usado antes. , que podría estar en conjunto con un contador etc., por lo que la información es incorrecta y las coordenadas del hiperancla se toman de una instancia de ancla anterior anterior. De esta manera, los enlaces apuntan a una posición incorrecta.\label
\lstinputlisting
listings
\refstepcounter
\label
\refstepcounter
\label
\refstepcounter
section
De hecho, \lstinputlisting
tiene una label=
opción para especificar el nombre de la etiqueta.
La siguiente es una forma muy reducida proporcionada por personas que no son MWE, pero funciona.
\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}
Respuesta2
En el proceso de publicar esta pregunta, ¡me encontré con la respuesta! (No es que lo entiendapor quéfunciona...)
si junta solo estos fragmentos en un archivo de prueba y los ejecuta
pdflatex test.tex; pdflatex test.tex
, ¡funciona bien! (Excepto que el hipervínculo en el número "1" en realidad va a la tabla de contenido, no a la página 1).
Cuando arrojaba errores, no me sorprendió que la hiperreferencia fuera al lugar equivocado. Sin embargo, con el caso de prueba reducido, estaba desconcertado. Así que comencé a leer sobreesoproblema y descubrí que lo que quería era \phantomsection
así:
\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}}
Observe que mi culto a la carga \hspace{1em}
ya no es necesario (AFAIK); y pude volver a colocar los caracteres especiales que lst:#1-#2
había reemplazado al foo#1#2
intentar reducir el caso de prueba.
... ¡Y por arte de magia, de repente mi gigantesco proyecto se compila bien! Ya no hay mensajes de error misteriosos. Todos los enlaces de hiperreferencia van a las páginas correctas y muestran el texto del cuerpo correcto.
No tengo idea de por qué la omisión \phantomsection
causó tanto estrago, pero después de colocarlo, ¡todo está arreglado!