
Я использую комбинацию xr-hyper
, hyperref
и cleveref
с несколькими файлами. Старый код, который у меня есть, больше не работает правильно. Внешние ссылки теперь включают имя файла extrenal, а не только номер ссылки.
В примере ниже я fileone
сначала компилирую, а затем filetwo
, что относится к разделу в fileone
. Вывод filetwo
тогда будет таким:
вместо просто Section 1
.
fileone.tex
\documentclass{article}
\usepackage{xr-hyper}
\usepackage{hyperref}
\usepackage{cleveref}
\begin{document}
\section{One}
\label{sec:one}
\end{document}
filetwo.tex
\documentclass{article}
\usepackage{xr-hyper}
\usepackage{hyperref}
\usepackage{cleveref}
\externaldocument{fileone}
\begin{document}
\Cref{sec:one}
\end{document}
Я подозреваю, что необходимо внести какие-то исправления cleveref
, но пока не могу точно сказать, какие именно.
Для справки версии файлов следующие:
xr-hyper.sty 2024-01-20 v7.01h eXternal References (DPC)
hyperref.sty 2024-01-20 v7.01h Hypertext links for LaTeX
cleveref.sty 2018/03/27 v0.21.4 Intelligent cross-referencing
решение1
Редактировать 2023-03-28
Первая помощь для Cleveref была добавлена в LaTeX, которая содержит переопределения, упомянутые в ответе. Со следующим релизом LaTeX и с выпущенным сегодня latex-dev ссылки снова будут правильными.
Старый ответ
В текущем LaTeX синтаксис \newlabel
в .aux
файле был унифицирован с синтаксисом, используемымhyperref
и всегда содержит пять контейнеров данных.cleveref
не был адаптирован к этому изменению и по-прежнему использует только два контейнера данных в своем определении. Поэтому ваш внешний .aux
файл содержит (я добавил несколько пробелов для лучшей видимости):
\newlabel{sec:one}{ {1} {1} {One} {section.1} {} } %<------- five
\newlabel{sec:one@cref}{ {[section][1][]1} {[1][1][]1} } %<------- two
Внутри документа не так уж важно, чтоcleveref
метка имеет только два контейнера данных, какcleveref
единственный, кто его использует. Ноxr-hyper
пытается придерживаться нового стандарта и расширяет каждую считываемую метку до пяти контейнеров данных. Он также использует пятый контейнер данных для хранения имени файла для ссылок.
Теперь, недавноxr-hyper
был расширен для хранения всегда имени файла (а не только если метка содержит имя назначения в четвертом контейнере), чтобы разрешить ссылки на файлы внешнего документа, даже если этот документ не использовалhyperref
. С этим изменением получаем следующие определения для меток из внешнего документа:
> \r@sec:one=macro:
->{1}{1}{One}{section.1}{fileone.pdf}.
> \r@sec:one@cref=macro:
->{[section][1][]1}{[1][1][]1}{}{}{fileone.pdf}.
% would be in older versions:
% ->{[section][1][]1}{[1][1][]1}{}{}{}.
А потомcleveref
падает fileone.pdf
в последнем аргументе.
Лучше всего было бы, если быcleveref
будет обновлено, чтобы всегда использовать стандартный контейнер данных пять, чтобы все было синхронизировано. На данный момент вы можете сделать что-то вроде этого:
\documentclass{article}
\usepackage{xr-hyper}
\usepackage{hyperref}
\usepackage{cleveref}
\externaldocument{fileone}
\makeatletter
\def\cref@getref#1#2{%
\expandafter\let\expandafter#2\csname r@#1@cref\endcsname%
\expandafter\expandafter\expandafter\def%
\expandafter\expandafter\expandafter#2%
\expandafter\expandafter\expandafter{%
\expandafter\@firstoffive#2}}% <-------- five
\def\cpageref@getref#1#2{%
\expandafter\let\expandafter#2\csname r@#1@cref\endcsname%
\expandafter\expandafter\expandafter\def%
\expandafter\expandafter\expandafter#2%
\expandafter\expandafter\expandafter{%
\expandafter\@secondoffive#2}}% <----------- five
\AtBeginDocument{%
\def\label@noarg#1{%
\cref@old@label{#1}%
\@bsphack%
\edef\@tempa{{page}{\the\c@page}}%
\setcounter{page}{1}%
\edef\@tempb{\thepage}%
\expandafter\setcounter\@tempa%
\cref@constructprefix{page}{\cref@result}%
\protected@write\@auxout{}%
{\string\newlabel{#1@cref}{{\cref@currentlabel}%
{[\@tempb][\arabic{page}][\cref@result]\thepage}{}{}{}}}% <----- five
\@esphack}%
\def\label@optarg[#1]#2{%
\cref@old@label{#2}%
\@bsphack%
\edef\@tempa{{page}{\the\c@page}}%
\setcounter{page}{1}%
\edef\@tempb{\thepage}%
\expandafter\setcounter\@tempa%
\cref@constructprefix{page}{\cref@result}%
\protected@edef\cref@currentlabel{%
\expandafter\cref@override@label@type%
\cref@currentlabel\@nil{#1}}%
\protected@write\@auxout{}%
{\string\newlabel{#2@cref}{{\cref@currentlabel}%
{[\@tempb][\arabic{page}][\cref@result]\thepage}{}{}{}}}% <------- five
\@esphack}%
}
\begin{document}
\Cref{sec:one}
\end{document}