10 如何在不手动更改`beamer.cls`第·376·行代码的情况下消除`hyperref`和`cleveref`之间的冲突?

发布于 2025-03-06 22:38:30

通过这个最小工作示例,编译会得到一条警告:

Package cleveref: hyperref package loaded with implicit=false option - disabling cleveref's hyperref support. This situation is not supported by cleveref, and there's no guarantee anything will work. You're on your own!.

由于beamer.cls376行的代码\RequirePackage[implicit=false]{hyperref},使用了implicit=false选项,这个选项的作用是“完全避免使用hyperref对外部命令(external commands)进行补丁”,而hyperref宏包文档说正在考虑对补丁进行分类,以可以用更精细的方式控制它们。

于是,发出的这条警告就是告诉我:通过第376行这种方式调用hyperref,就会使得cleveref无法正常工作。那么我的解决方法是直接更改beamer.cls376行代码为\RequirePackage[implicit=true]{hyperref},很好,警告消失了。

但是,我并不希望直接手动更改beamer.cls源码,因为我在另一台电脑上无法使用本地发行版,所以我希望能在最小工作示例中对beamer.cls376行进行更改,这该怎么做呢?有没有什么工具可以实现?

查看更多

关注者
1
被浏览
1.1k
3 个回答
Sagittarius Rover
Sagittarius Rover 2025-03-07
这家伙很懒,什么也没写!

这不算是一个回答

可以缩短mwe:

\documentclass{beamer}
\usepackage{cleveref}
\begin{document}
\begin{frame}
    Hello, world!   
\end{frame}
\end{document}

甚至可以只是:

\documentclass{article}
\usepackage[implicit=false]{hyperref}
\usepackage{cleveref}
\begin{document}
    Hello, world!   
\end{document}

maybe related link:
OP的一个来源on TSE

Joseph Wright的回复

Samcarter的锐评


一点小探索,一般的宏包在使用global option指定选项之后,均可以通过:\<package>setup之类的命令实现覆盖(overwritten),但这对于hyperref并不奏效,查看hyperref.sty(需要pdflatex hyperref.dtx)可以发现:

当传入impilicit=false时,由于:

%Line2283 将其默认值设置为true
\define@key{Hyp}{implicit}[true]{%
  \Hy@boolkey{implicit}{#1}%
}

同时这会触发所谓的patch external commands

% Line 4179~4203
\ifHy@implicit
  \Hy@InfoNoLine{Implicit mode ON; LaTeX internals redefined}%
\else
  \Hy@InfoNoLine{Implicit mode OFF; no redefinition of LaTeX internals}%
  \def\MaybeStopEarly{%
    \Hy@Message{Stopped early}%
    \Hy@AtBeginDocument{%
      \PDF@FinishDoc
      \gdef\PDF@FinishDoc{}%
    }%
    \endinput
  }%
  \Hy@AtBeginDocument{%
    \let\autoref\ref
    \let\autopageref\pageref
    \ifx\@pdfpagemode\@empty
      \gdef\@pdfpagemode{UseNone}%
    \fi
    \global\Hy@backreffalse
  }%
  \Hy@AtEndOfPackage{%
    \global\let\ReadBookmarks\relax
    \global\let\WriteBookmarks\relax
  }%
\fi

%Line 4521~4540
\ifHy@implicit
      \let \T@Ref\HyRef@Ref
      \def\@refstar#1{%
        \NR@ref@showkeys{#1}%
        \HyRef@StarSetRef{#1}\@firstoffive
      }
      \def\@pagerefstar#1{%
        \NR@ref@showkeys{#1}%
        \HyRef@StarSetRef{#1}\@secondoffive
      }
      \def\@namerefstar#1{%
        \NR@ref@showkeys{#1}%
        \HyRef@StarSetRef{#1}\@thirdoffive
      }
      \def\@Refstar#1{%
        \NR@ref@showkeys{#1}%
        \HyRef@StarSetRef{#1}\HyRef@MakeUppercaseFirstOfFive
      }%
     \else
     \fi

且与此同时在:

% Line4204
\Hy@DisableOption{implicit}

这也解释了即使使用\hypersetup{}main.tex中再次显式设置implicit选项,也无法修改beamer.cls\RequirePackage[implicit=false]{hyperref}的显式设置的原因.

我猜这种设计是因为implicit所进行的操作均为内部patch,因此disabled了用户从外部修改implicit的接口以防止奇怪的更改。

鱼香肉丝没有鱼先生
脾气不好,别来惹我!!!

我来测试一下

Sagittarius Rover
Sagittarius Rover 2025-11-03
这家伙很懒,什么也没写!

2025年,可以不用cleveref而改用zref-clever:

\documentclass{beamer}
\usepackage{hyperref}
% \usepackage{cleveref}
% \crefformat{equation}{\mbox{Eq. #2(#1)#3}}
% \crefrangeformat{equation}{\mbox{Eqs. #3(#1)#4 to #5(#2)#6}}
% \crefmultiformat{equation}{\mbox{Eqs. #2(#1)#3}}{ and #2(#1)#3}{, #2(#1)#3}{ and #2(#1)#3}
% \crefrangemultiformat{equation}{\mbox{Eqs. #3(#1)#4 to #5(#2)#6}}{ and #3(#1)#4 to #5(#2)#6}{, #3(#1)#4 to #5(#2)#6}{ and #3(#1)#4 to #5(#2)#6}

\usepackage{zref-clever}
\zcRefTypeSetup{equation}{
    name-sg={eq.},
    name-pl={eqs.},
    Name-sg={Eq.},
    Name-pl={Eqs.},
}

\begin{document}

\begin{frame}{Title Here}

    \begin{block}

        \begin{align}
            A  &= B
            \label{eq1}
            \\
             &= C
             \label{eq2}
             \\
             &= D
             \label{eq3}
        \end{align}

    \end{block}

\end{frame}


\begin{frame}{Title Here}

    \begin{block}

        \begin{align}
            A  &= B
            \label{eq4}
            \\
             &= C
             \label{eq5}
             \\
             &= D
             \label{eq6}
        \end{align}

    \end{block}

\end{frame}

\begin{frame}{Title Here}

\begin{block}

    \begin{align}
    A  &= B
    \label{eq7}
    \\
    &= C
    \label{eq8}
    \\
    &= D
    \label{eq9}
    \end{align}

\end{block}

\end{frame}

\begin{frame}
    contents in between
\end{frame}


\begin{frame}

    % \cref{eq1} 

    % \cref{eq1,,eq2}

    % \cref{eq1,eq2,eq3} 

    % \cref{eq1,eq2,eq3,eq7,eq8,eq9} 

    % \cref{eq1,,eq2,,eq3,eq7,eq8,eq9} 

    % \cref{eq6,eq7,eq9} 

    % Eq. \ref{eq1} 
   

    \zcref[S]{eq1} 

    \zcref[S]{eq1,,eq2}

    \zcref[S]{eq1,eq2,eq3} 

    \zcref[S]{eq1,eq2,eq3,eq7,eq8,eq9} 

    \zcref[S]{eq1,,eq2,,eq3,eq7,eq8,eq9} % I want "Eqs. (1),(2),(3) and (7) to (9)"

    \zcref[S]{eq6,eq7,eq9} 

    Eq. \zref{eq1} 
\end{frame}

\end{document}

这样不会报任何警告,虽然「编号形式受到\seq_set_from_clist:Nnclist的解析小问题」,但是很少会用到\cref{eq1,,eq2,,eq3,eq7,eq8,eq9}这样故意空格的需求...

image.png

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览