我正在寻找一种将 cleveref 和 hyperref 与 clrscode3e 包结合使用的方法。不幸的是,这两个包不能立即一起使用。
更准确地说,我正在考虑以下用例。对于给定的代码框,我希望能够标记一行,然后使用命令在文本中引用它\cref
。排版时,这应该打印一个可点击的行号,超链接回代码框中的行。下面描绘了一个 MWE。
\documentclass{article}
\usepackage{hyperref}
\usepackage{cleveref}
\usepackage{clrscode3e}
\begin{document}
\begin{codebox}
\Procname{$\proc{MWE}$}
\li $x \gets 1$ \label{lin:assign}
\End
\end{codebox}
As shown in \cref{lin:assign}, \dots
\end{document}
不久前我发布了一个类似的问题:使用 clrscode3e 的 Cleveref。然而,该问题并未涉及使用 hyperref,因此解决方案无法一一映射。更准确地说,原因是 hyperref 创建的超链接始终指向文档中的第一个代码框,无论包含标签的代码框是什么。
答案1
您需要确保 hyperref 目标名称是唯一的。hyperref 使用(如果存在)命令\theH<counter>
。由于您的代码框没有计数器,因此必须对标签进行编号:
\documentclass{article}
\usepackage{clrscode3e}
\usepackage{hyperref}
\usepackage{cleveref}
\crefname{codelinenumber}{code}{code} %adapt
\newcounter{codelabel}
\newcommand\theHcodelinenumber{\thecodelabel.\thecodelinenumber}
\newcommand\clrslabel[1]
{\stepcounter{codelabel}%
\addtocounter{codelinenumber}{-1}%
\refstepcounter{codelinenumber}%
\label{#1}}
\begin{document}
\begin{codebox}
\Procname{$\proc{MWE}$}
\li $x \gets 1$ \clrslabel{lin:assign}
\End
\end{codebox}
As shown in \cref{lin:assign}, \cref{lin:assign2}\dots
\newpage
\begin{codebox}
\Procname{$\proc{MWE}$}
\li $x \gets 1$ \clrslabel{lin:assign2}
\End
\end{codebox}
\end{document}