标题中的交叉引用,fancyhdr 和 hyperref 之间的冲突

标题中的交叉引用,fancyhdr 和 hyperref 之间的冲突

我正在写论文,并使用fancyhdr来作为标题。只是标准的“奇数页上的章节名称和偶数页上的节名称”。我还需要使用该hyperref包来分解参考书目中的长网址。我的问题是,当我使用此包(和breakurl)时,标题中的交叉引用显示为问号。也就是说,如果我有一个节/章的名称包含对方程式的引用,则该引用不会在标题中正确显示。

下面是一个最小示例。编译后,请参见第 15 页中的标题。如果我注释掉

\usepackage[breaklinks=true]{hyperref}
\usepackage{breakurl}

标题正确显示参考。

有什么想法可以解释为什么或如何解决这个问题吗?

\documentclass[a4paper,11pt,twoside]{book}

\usepackage[rmargin=2cm,includeheadfoot,bmargin=2cm,tmargin=3cm, lmargin=4cm]{geometry}
\usepackage{fancyhdr}
\pagestyle{fancy}
\lhead[]{\footnotesize{\leftmark}}
\rhead[\footnotesize{\rightmark}]{}
\bibliographystyle{plain}

%If I comment the following two lines, no problem.
\usepackage[breaklinks=true]{hyperref}
\usepackage{breakurl}


\begin{document}

\title{Fake Title}
\author{Me}
\date{\today}
\maketitle

\chapter{First Chapter}

\section{First}
a \newpage b \newpage c \newpage
\section{Second}
\begin{equation}
x=2
\label{eq:myEquation}
\end{equation}
a \newpage b \newpage c \newpage
\section{Third}
\label{sec:thirdSection}
a \newpage b \newpage c \newpage

\chapter{Some thoughts about Section~\ref{sec:thirdSection}}
\section{First}
a \newpage b \newpage c \newpage
\section{About Equation~\ref{eq:myEquation}}
a \newpage b \newpage c \newpage
\section{First}
a \newpage b \newpage c \newpage
\end{document}

答案1

问题在于标题是大写的。即使没有大写,hyperref你也会收到类似这样的警告

LATEX WARNING: REFERENCE `SEC:THIRDSECTION' ON PAGE 13 UNDEFINED on input line 44.

如果hyperref已加载,则\ref不可扩展,并且其参数在用于获取参考数据之前会转换为大写。

有几种方法可以解决这个问题。一种方法是使用包含及其参数的强大宏。然后,如果在中使用并且参数未转换为大写,\ref则此命令不会展开:\MakeUppercase

% before \tableofcontents
\DeclareRobustCommand*{\RefSecThirdSection}{\ref{sec:thirdSection}}
\begin{document}
...
\tableofcontents
...
\chapter{Some thoughts about Section~\RefSecThirdSection}

由于书签的原因,使用 e-TeX\protected\def代替 LaTeX\DeclareRobustCommand不会有帮助。已\MakeUppercase禁用,命令再次可扩展。替代方案是\pdfstringdefDisableCommands

\protected\def\RefSecThirdSection{\ref{sec:thirdSection}}
\pdfstringdefDisableCommands{%
  \def\RefSecThirdSection{\ref{sec:thirdSection}}%
}

为了方便起见,可以将其放入宏中,例如:

\newcommand*{\headref}[1]{%
  \csname headref@#1\endcsname
}
\newcommand*{\declareheadref}[1]{%
  \protected\expandafter\def\csname headref@#1\endcsname{%
    \ref{#1}%
  }%
  \expandafter\pdfstringdefDisableCommands\expandafter{%
    \expandafter\def\csname headref@#1\endcsname{%
      \ref{#1}%
    }%
  }%
}
\declareheadref{sec:thirdSection}
\begin{document}
...
\tableofcontents
...
\chapter{Some thoughts about Section~\headref{sec:thirdSection}}

由于 的可扩展性\headref,标签名称无法支持 babel 简写。

如果您不想要链接,那么可以使用 \getrefnumber包。是可扩展的,因此引用的内容会转换为大写,而不是标签名称。refcount\getrefnumber

\usepackage{refcount}
...
\refused{sec:thirdSection}
\chapter{Some thoughts about Section~\getrefnumber{sec:thirdSection}}

第三种方法是首先使用大写的标签名称:

\label{SEC:THIRDSECTION}
...
\chapter{Some thoughts about Section~\ref{SEC:THIRDSECTION}}

答案2

正如 Stephan 所说,用大写字母书写标签应该可以解决问题,因为修改的\MakeUppercase参数显然不存在。但是,您也可以使用辅助宏来隐藏大小写更改:\ref{sec:thirdSection}\ref{SEC:THIRDSECTION}\MakeUppercase

\newcommand{\RthirdSection}{\ref{sec:thirdSection}}
\chapter{Some thoughts about Section~\protect\RthirdSection}
%...
\newcommand{\RmyEquation}{\ref{eq:myEquation}}
\section{About Equation~\protect\RmyEquation}

请注意,您还必须\protect使用宏。

此建议源自 TeX FAQ 条目大小写转换的奇怪现象

答案3

对文档进行最少更改(不添加新宏或更改现有标签/引用)的解决方案是添加大写版本作为第二标签上被引用的项目。例如,如果有问题的引用是

\begin{theorem}\label{mainresult} Suppose... 
\end{theorem}

\section{Proof of Theorem~\ref{mainresult}}

添加另一个标签会使引用在标题中起作用,而无需进行其他更改。

\begin{theorem}\label{mainresult}\label{MAINRESULT} Suppose... 
\end{theorem}

\section{Proof of Theorem~\ref{mainresult}}

虽然这不像保护引用不被大写转换那么优雅,但它很有意思,因为在同一个项目上放置两个标签是有意义的罕见情况。

相关内容