xr-hyper と cleveref は make4ht でコンパイルできません

xr-hyper と cleveref は make4ht でコンパイルできません

私は、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を(cleverefの使用をやめる)に変更しても\ref、make4htはエラーを出さずにコンパイルできません。

[ERROR]   htlatex: ./ref.tex    10   Argument of \XR:rEfLiNK has an extra }.

バッチモードを使用してコンパイルすると、期待どおりの HTML が生成されます。その後でコンパイルしようとすると、さらに多くのエラーが発生し、バッチモードが使用されている場合は参照が機能しません。以前に\crefコンパイルした場合はエラーは発生しませんが、明らかに相互参照は機能しません。ref.texmain.tex

以前、make4ht xr-hyperとhyperrefでほぼ同じバグが議論されていました。ここその後修正されました。

これを回避する方法をご存知の方はいらっしゃいますか? また、どのプロジェクトにバグを報告するのが良いでしょうか?

答え1

問題が 2 つあります。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ラベルを検出し、それに応じて指定された参照を宣言します。

もう 1 つの問題は にあります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

これらの変更を加えると、例をコンパイルできるようになります。

ここに画像の説明を入力してください

関連情報