我在使用以下 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
您可以替换\cref
by\crtcref
和\Cref
by \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}