Я пытаюсь использовать CleverEf для перекрестных ссылок между документами и компилировать их с помощью make4ht. Следующий пример компилируется с помощью pdflatex, но не с помощью make4ht или htlatex.
main.tex
:
\documentclass{article}
\usepackage{hyperref}
\usepackage{cleveref}
\begin{document}
\section{First Section} \label{section}
\begin{equation} \label{equation}
\int f(x) dx
\end{equation}
\end{document}
ref.tex
:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xr-hyper}
\usepackage{hyperref}
\usepackage{cleveref}
\externaldocument[main-]{main}
\begin{document}
Equation \eqref{main-equation} in \cref{main-section}.
\end{document}
Если я изменю \cref
на \ref
(прекращу использование cleveref), то make4ht все равно не сможет скомпилироваться без выдачи ошибки
[ERROR] htlatex: ./ref.tex 10 Argument of \XR:rEfLiNK has an extra }.
Если скомпилировано с использованием batchmode, то создается ожидаемый html. Если я пытаюсь скомпилировать с помощью batchmode, то \cref
получаю кучу ошибок, и ссылки не работают, если используется batchmode. Если я скомпилирую ref.tex
до main.tex
этого, то ошибок нет, но, очевидно, тогда перекрестные ссылки не работают.
Раньше была почти идентичная ошибка с make4ht xr-hyper и hyperref, которая обсуждаласьздеськоторая с тех пор была исправлена.
Кто-нибудь знает, как это обойти? Также в какой проект лучше всего сообщить об ошибке?
решение1
Есть две проблемы. Первая заключается в том, что TeX4ht необходимо загрузить файл aux
из main.tex
. Когда он это делает, он проверяет все метки и изменяет их так, чтобы они создавали правильные ссылки на файл main.html
. Однако Cleveref использует специальные метки с метаинформацией о типе ссылки данной метки. Эти специальные метки используют суффикс @cref
. Мы должны игнорировать их. Эта версия файла xr-hyper.4ht
делает это:
% xr-hyper.4ht (2023-03-10-16:43), generated from tex4ht-4ht.tex
% Copyright 2003-2009 Eitan M. Gurari
% Copyright 2009-2023 TeX Users Group
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3c of this license or (at your option) any
% later version. The latest version of this license is in
% http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions
% of LaTeX version 2005/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
%
% The Current Maintainer of this work
% is the TeX4ht Project <http://tug.org/tex4ht>.
%
% If you modify this program, changing the
% version identification would be appreciated.
\immediate\write-1{version 2023-03-10-16:43}
\let\XR:loop=\XR@loop
\def\XR@loop#1{%
\def\:temp##1.aux{\openin15=##1.xref
\ifeof15
\:warning{missing ##1.xref for ##1.aux}%
\let\:temp\empty
\else
\def\:temp{\input ##1.xref}%
\fi
\closein15 \:temp
}%
\catcode`\:=11
\expandafter\ifx \csname xr:CrossWord\endcsname\relax
\let\xr:CrossWord=\Cross:Word
\def\Cross:Word##1##2{%
\expandafter\let\csname cw:\cw:format{##1##2}\endcsname\:UnDef
\xr:CrossWord{##1}{##2}}%
\fi
%
\:temp#1%
\catcode`\:=12
\XR:loop{#1}%
}
\ExplSyntaxOn
\long\def\XR@test#1#2#3#4\XR@{%
\ifx#1\newlabel
\regex_match:nnTF{@cref}{#2}% we must handle cleveref meta references
{\expandafter\xdef\csname r@\XR@prefix#2\endcsname{#3}}%
{\expandafter\xdef\csname r@\XR@prefix#2\endcsname{\XR:rEfLiNK #3}}%
%
\else\ifx#1\@input
\edef\XR@list{\XR@list#2\relax}%
\fi\fi
\ifeof\@inputcheck\expandafter\XR@aux
\else\expandafter\XR@read\fi}
\ExplSyntaxOff
\def\XRrEfLiNK[#1]#2#3{%
\filename@parse{#1}% Get basename of the linked html file,
% xr:dir\filename@base contains file's directory
\a:xr[\csname xr:dir:\filename@base\endcsname#1]{#2}{}%
% this extra \fi fixes warning about unclosed \ifx, I hope it doesn't break anything
% I cannot find where that \ifx starts
\ifx\hyperrefLabel\:UnDef #3\else \hyperrefLabel\fi \b:xr\fi}
\NewConfigure{xr}{2}
\Configure{xr}{\Link}{\EndLink}
\def\XR:rEfLiNK#1#2#3#4#5{{\xr:rEfLiNK#1}{\xr:rEfLiNK#2}{\xr:rEfLiNK#3}}
\def\xr:rEfLiNK#1#2{\noexpand\XRrEfLiNK[\Get:HFile#2-]{#2}}
\def\Get:HFile#1-#2-{\:LikeRef{)F\:gobble #1F-}}
\Hinput{xr}
\endinput
Вот важный код:
\ExplSyntaxOn
\long\def\XR@test#1#2#3#4\XR@{%
\ifx#1\newlabel
\regex_match:nnTF{@cref}{#2}% we must handle cleveref meta references
{\expandafter\xdef\csname r@\XR@prefix#2\endcsname{#3}}%
{\expandafter\xdef\csname r@\XR@prefix#2\endcsname{\XR:rEfLiNK #3}}%
%
\else\ifx#1\@input
\edef\XR@list{\XR@list#2\relax}%
\fi\fi
\ifeof\@inputcheck\expandafter\XR@aux
\else\expandafter\XR@read\fi}
\ExplSyntaxOff
Он использует регулярное выражение LaTeX 3 для обнаружения @cref
меток и соответствующим образом объявляет заданную ссылку.
Другая проблема в cleveref.4ht
, потому что нам нужно поддерживать специальные внешние файловые ссылки, введенные в предыдущей функции. Эта версия cleveref.4ht
должна исправить это:
% cleveref.4ht (2023-03-10-17:14), generated from tex4ht-4ht.tex
% Copyright 2018-2023 TeX Users Group
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3c of this license or (at your option) any
% later version. The latest version of this license is in
% http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions
% of LaTeX version 2005/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
%
% The Current Maintainer of this work
% is the TeX4ht Project <http://tug.org/tex4ht>.
%
% If you modify this program, changing the
% version identification would be appreciated.
\immediate\write-1{version 2023-03-10-17:14}
% orig:refstepcounter is saved in cleveref-hooks.4ht
\let\cref@old@refstepcounter\orig:refstepcounter%
\def\refstepcounter{%
\@ifnextchar[{\refstepcounter@optarg}{\refstepcounter@noarg}%]
}%
% fix for TeX4ht label mechanism
\def\cref:currentlabel#1{\let\cnt:currentlabel\@currentlabel
\def\:@currentlabel{\ifx \cnt:currentlabel\@currentlabel
\expandafter\the\csname c@#1\endcsname\else \@currentlabel\fi}%
%
\anc:lbl r{#1}%
}
\def\refstepcounter@noarg#1{%
\cref@old@refstepcounter{#1}%
\cref@constructprefix{#1}{\cref@result}%
\@ifundefined{cref@#1@alias}%
{\def\@tempa{#1}}%
{\def\@tempa{\csname cref@#1@alias\endcsname}}%
\protected@xdef\cref@currentlabel{%
[\@tempa][\arabic{#1}][\cref@result]%
\csname p@#1\endcsname\csname the#1\endcsname}%
\cref:currentlabel{#1}%
}%
\def\refstepcounter@optarg[#1]#2{%
\cref@old@refstepcounter{#2}%
\cref@constructprefix{#2}{\cref@result}%
\@ifundefined{cref@#1@alias}%
{\def\@tempa{#1}}%
{\def\@tempa{\csname cref@#1@alias\endcsname}}%
\protected@xdef\cref@currentlabel{%
[\@tempa][\arabic{#2}][\cref@result]%
\csname p@#2\endcsname\csname the#2\endcsname}%
\cref:currentlabel{#2}%
}%
\ifdefined\@firstoffive\else%
\def\@firstoffive#1#2#3#4#5{#1}%
\fi
\def\:tempa#1#2{\bgroup%
\def\rEfLiNK##1##2{\Link{##1}{}}%
\def\XRrEfLiNK[##1]##2##3{\Link[##1]{##2}{}}% handle links from Xr and Xr-hyper
\expandafter\expandafter\expandafter\@firstoffive\csname r@#2\endcsname{}{}{}{}{}%
\cref@getlabel{#2}{\@templabel}%
#1{\@templabel}{}{}%
\EndLink\egroup%
}%
\HLet\@@@setcref=\:tempa
\@ifpackageloaded{amsthm}{
\let\cref@thmnoarg\@thm%
\def\@thm{\@ifnextchar[{\cref@thmoptarg}{\cref@thmnoarg}}%]
\def\:tempb[#1]#2#3#4{%
% call original amsthm theorem definition, but
% disable \:thm in order to prevent infinite loop
\let\:thm\:gobble%
\cref@thmnoarg{#2}%
\o:cref@thmoptarg:[#1]{#2}{#3}{#4}
}%
\HLet\cref@thmoptarg\:tempb%
}{}%
\Hinput{cleveref}
\endinput
Вот важный код:
\def\:tempa#1#2{\bgroup%
\def\rEfLiNK##1##2{\Link{##1}{}}%
\def\XRrEfLiNK[##1]##2##3{\Link[##1]{##2}{}}% handle links from Xr and Xr-hyper
\expandafter\expandafter\expandafter\@firstoffive\csname r@#2\endcsname{}{}{}{}{}%
\cref@getlabel{#2}{\@templabel}%
#1{\@templabel}{}{}%
\EndLink\egroup%
}%
\HLet\@@@setcref=\:tempa
Нам нужно заявить об этом \def\XRrEfLiNK[##1]##2##3
здесь.
С этими изменениями вы сможете скомпилировать свой пример: