在 \section 中使用 cleveref 时 hyperref 发出警告

在 \section 中使用 cleveref 时 hyperref 发出警告

我在使用以下 MWE 时遇到了一个小问题,但很烦人

\documentclass{article}

\usepackage{hyperref,cleveref}
\newtheorem{thm}{Theorem}

\begin{document}

\begin{thm}\label{good}
    Cleveref is good
\end{thm}

\section{Proof of \Cref{good}}
    It is trivial.

\end{document}

编译器(pdflatex)抱怨

Package hyperref Warning: Token not allowed in a PDF string (PDFDocEncoding):
(hyperref)                removing `\@ifnextchar' on input line 13.

此外,PDF TOC 显示的Proof of good是 而不是Proof Theorem 1。除了说 之外还有其他解决方案吗\section{Proof of Theorem \ref{...}}?毕竟,使用 的全部目的cleveref不是为了重复good是定理这一事实。

PS1. 我也想要一个或更多通用文档类的解决方案amsart。(也就是说,s 的顺序\usepackage或多或少是固定的)

PS2. 请随意标记重复。尽管我在这个网站上看到的其他 MWE 远非最低限度。

答案1

正如我在评论中所说,问题在于cleveref的机制不可扩展(例如,\@ifnextchar抱怨hyperref的不可扩展),因此它不能变成 PDF 字符串。

crossreftools软件包提供了交叉引用命令的可扩展替代方案。cleverref您可以替换\crefby\crtcref\Crefby \crtCref

但是,正如您在评论中指出的那样,仅使用那个会严重中断。原因是cleverref重新定义了定理的一些内部结构并插入了一些\MakeUppercase\MakeLowercase(不可扩展)。问题归结为这些命令最终出现在交叉引用代码中,而交叉引用代码预计只包含文本。当hyperref尝试扩展它时,就会出现混乱。

我尝试找到一个合适的解决方案,但大多数解决方案都会导致代码混乱,与所有内容都不兼容。一种更简单的解决方法cleveref是使用 的大小写更改函数,既能保留 的功能,又能使交叉引用文本可扩展expl3。我使用etoolbox分别将命令、和中的 和 替换为 和。\patchcmd修补后,可扩展性问题就不复存在了 :-)\MakeUppercase\MakeLowercase\text_uppercase:n\text_uppercase:n\@othm\@xnthm\@ynthm

PDF:

在此处输入图片描述

和 pdf 书签文件:

\BOOKMARK [1][-]{section.1}{Proof of Theorem 1}{}% 1

代码:

\documentclass{article}

\usepackage{expl3,etoolbox}

\usepackage{hyperref,cleveref}
\usepackage{crossreftools}

% This patch must be after loading cleverref and before defining a new theorem
\ExplSyntaxOn
\makeatletter
\clist_map_inline:nn { \@othm, \@xnthm, \@ynthm }
  {
    \patchcmd #1 { \MakeUppercase } { \text_uppercase:n } { } { \FAILED: }
    \patchcmd #1 { \MakeUppercase } { \text_uppercase:n } { } { \FAILED: }
    \patchcmd #1 { \MakeLowercase } { \text_lowercase:n } { } { \FAILED: }
  }
\makeatother
\ExplSyntaxOff

\newtheorem{thm}{Theorem}

\begin{document}

\begin{thm}\label{good}
    Cleveref is good. expl3 is awesome :D
\end{thm}

\section{Proof of \crtCref{good}}
    It is trivial.

\end{document}

相关内容