1

I found that tex4ht doesn't work with cleveref and amsthm. I just modified the HWE from an old post:

\documentclass{article}
\usepackage{hyperref}
\usepackage{amsthm}
\usepackage{cleveref}
\newtheorem{thm}{Theorem}[section]
\newtheorem{rmk}[thm]{Remark}
\begin{document}
\begin{rmk}\label{test}
Test content
\end{rmk}

See the test found in \cref{test}
\end{document}

When I compile it with htlatex, it complains:

! Argument of \eorem:syle has an extra }.
<inserted text> 
                \par 
l.8 \begin{rmk}
               \label{test}

This answer suggests \AtBeginDocument. However, then the \cref will be rendered wrongly as ??. I wonder a workaround for this.

1 Answer 1

1

The problem is that Cleveref redefines lot of other macros and packages, which clashes with TeX4ht. It even adds an optional argument for \refstepcounter, which fails miserably with TeX4ht. So we need to redefine these redefined macros again and insert TeX4ht instructions that are necessary for it's referencing system to work.

First of all, we need to preserve the original version of \refstepcounter. This needs to be done before cleveref.sty is loaded. TeX4ht can modify the package loading using the cleveref-hooks.4ht file:

\let\HyOrg@addtoreset\@addtoreset
% fixes for \refstepcounter
\let\orig:refstepcounter\refstepcounter
\let\orig:@thm\@thm
\:AtEndOfPackage{%
\let\refstepcounter\orig:refstepcounter
\let\@thm\orig:@thm
}

We basically reset the modifications done to \refstepcounter by Cleveref. Next, we must add the support for the \refstepcounter optional argument and amsthm in cleveref.4ht:

% 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}{}}%
  \expandafter\expandafter\expandafter\@firstoffive\csname r@#2\endcsname{}{}{}{}{}%
  \o:@@@setcref:{#1}{#2}%
  \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

With these fixes, the compilation works and creates a correct HTML:

enter image description here

2
  • A quick remark is that we also need to do with \Cref. And what about other environments (like theorem, lemma, definition, etc.)?
    – Yai0Phah
    Jun 30, 2021 at 14:18
  • @Yai0Phah it uses low-level commands, so it should work for \Cref and all environments defined using \newtheorem
    – michal.h21
    Jun 30, 2021 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.