标题内的 \cref 会破坏 PDF 书签

标题内的 \cref 会破坏 PDF 书签

在以下 MWE 中,hyperref 生成的书签不正确:

\documentclass{article} 
\usepackage{hyperref}
\usepackage[capitalize,nameinlink,noabbrev]{cleveref}

\hypersetup{%
    bookmarksnumbered, bookmarksopen=true, bookmarksopenlevel=1,%
}   

\begin{document} 
\section{\label{sec:foo}foo}
\section{Code for \cref{sec:foo}}
\end{document}

PDF 中第 2 部分的标题是正确的 ( Code for Section 1),但 Acrobat 中显示的书签如下:

1 foo
2 Code for sec:foo

编辑:正如 Micha 指出的那样,该代码还会产生警告:

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

\protect不幸的是,之前使用 allmighty\cref并没有改变任何东西 ;)。

答案1

您(重新)发现了 TeX 处理某些项目(例如书签)的能力的基本限制。请注意,此限制不仅限于处理\cref指令。

为了绕过这个限制,您可以使用(诚然有些笨拙的)命令\texorpdfstring,它需要两个参数。第一个是应该在“TeX 端”显示的内容(基本上就是应该在正文中显示的内容),第二个是应该在“pdf 端”显示的内容,例如在书签中。

因此,MWE 的修改形式将如下所示:

\documentclass{article}
\usepackage{hyperref}
\usepackage[capitalize,nameinlink,noabbrev]{cleveref}
\hypersetup{%
    bookmarksnumbered, bookmarksopen=true, bookmarksopenlevel=1,%
}
\begin{document}
\section{foo} \label{sec:foo}
\section{Code for \texorpdfstring{\cref{sec:foo}}{Section \ref{sec:foo}}}
\end{document}

第一个参数将生成从第二个节标题文本到第一个节标题的超链接,第二个参数提供书签中显示内容的信息。通过此设置,第二节的书签将显示“第 1 节的代码”。

答案2

基于菲利佩·奥莱尼克的解决方案:https://tex.stackexchange.com/a/485979/128042 可以将该crossreftools包与一些自定义代码一起使用。

\documentclass{article} 
\usepackage{hyperref}
\usepackage[capitalize,nameinlink,noabbrev]{cleveref}
\usepackage{crossreftools}
\pdfstringdefDisableCommands{%
    \let\Cref\crtCref
    \let\cref\crtcref
}

\hypersetup{%
    bookmarksnumbered, bookmarksopen=true, bookmarksopenlevel=1,%
}


\begin{document} 
    \section{\label{sec:foo}foo}
    \section{Code for \cref{sec:foo}}
\end{document}

这会自动创建正确的 pdf 书签(在 TexXStudio 中必须编译两次)。(如果您还想删除链接的颜色,请参阅 菲利佩·奥莱尼克的解决方案:https://tex.stackexchange.com/a/485979/128042

PS:这个答案也得到了改进乌尔丽克·菲舍尔评论https://tex.stackexchange.com/a/504970/128042(回答等效问题pdf 书签(章节标题)中 \ref 的自动 \texorpdfstring)。

相关内容