Cleveref ошибочно отображает имя файла во внешних ссылках

Cleveref ошибочно отображает имя файла во внешних ссылках

Я использую комбинацию 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}

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