Я пишу свою диссертацию и использую 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}}
Хотя это не так элегантно, как защита ссылки от преобразования в верхний регистр, это представляет определенный интерес как редкий случай, когда размещение двух меток на одном элементе имеет смысл.