Перекрестные ссылки в заголовках, конфликт между fancyhdr и hyperref

Перекрестные ссылки в заголовках, конфликт между fancyhdr и hyperref

Я пишу свою диссертацию и использую fancyhdrдля заголовков. Просто стандартное "Название главы на нечетных страницах и название раздела на четных страницах". Мне также нужно использовать пакет hyperrefдля разбиения длинных URL-адресов в моей библиографии. Проблема в том, что когда я использую этот пакет (и 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's \protected\defвместо LaTeX's \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

Как упомянул Стефан, написание меток ВСЕМИ ЗАГЛАВНЫМИ БУКВАМИ должно исправить проблему, так как \MakeUppercaseизменяет аргумент \ref{sec:thirdSection}to \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.Странности, меняющие дело.

решение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}}

Хотя это не так элегантно, как защита ссылки от преобразования в верхний регистр, это представляет определенный интерес как редкий случай, когда размещение двух меток на одном элементе имеет смысл.

Связанный контент