我在使用算法时遇到了反向引用问题。
考虑以下示例
\documentclass{article}
\usepackage[algo2e,linesnumbered,algonl]{algorithm2e}
\usepackage[backref=section]{hyperref}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@misc{myarticle,
author = {ABC},
title = {A Title},
year = {2023},
}
\end{filecontents}
\begin{document}
\section{Test}
\subsection{Test}
\subsubsection{Test}
% comment/uncomment the algorithm
\begin{algorithm2e}
$a=b$\;
$b=c$\;
$c=d$\;
\end{algorithm2e}
\paragraph{Test}
Citing~\cite{myarticle}.
\bibliographystyle{plain}
\bibliography{\jobname}
\end{document}
反向引用显然将算法的最后一行号作为最后一个标签,而不是最后一节。如果算法被注释掉,我会看到预期的行为,并且反向引用引用该节。
使用算法
没有算法:
有什么解决方法吗?似乎\@currentlabel
在算法中被覆盖了。可以在算法之前存储部分标签,然后在算法之后恢复吗?
答案1
backref=section
实际上并没有选择节级别。例如,如果你这样做
\newtheorem{theorem}{Theorem}
和
\begin{theorem}
Something with \cite{myarticle}
\end{theorem}
反向引用将显示定理编号(测试它)。实际发生的是hyperref
获取当前值,\@currentlabel
但决不保证它是当前节编号。
在常见情况下似乎可以工作,只要你的\cite
命令不在进行自己编号的环境中(例如theorem
上面)。
你说,这应该适用于algorithm2e
环境。不,抱歉。原因algorithm2e
是坏事™,即
\gdef\@currentlabel{...}
与行号相关,因此在使用命令时\cite
,\@currentlabel
指向算法中的最后一行号。
结论:backref=section
不可靠。
完整示例。
\begin{filecontents*}{\jobname.bib}
@misc{myarticle,
author = {ABC},
title = {A Title},
year = {2023},
}
\end{filecontents*}
\documentclass{article}
\usepackage[algo2e,linesnumbered,algonl]{algorithm2e}
\usepackage[backref=section]{hyperref}
\newtheorem{theorem}{Theorem}
\renewcommand{\thetheorem}{!!!\arabic{theorem}!!!}% very distinctive
\begin{document}
\section{Test}
\subsection{Test}
\subsubsection{Test}
\cite{myarticle}
% comment/uncomment the algorithm
\begin{algorithm2e}
$a=b$\;
$b=c$\;
$c=d$\;
\end{algorithm2e}
\paragraph{Test}
\cite{myarticle}
\begin{theorem}Citing~\cite{myarticle}.\end{theorem}
\bibliographystyle{plain}
\bibliography{\jobname}
\end{document}
可能的解决方法(有许多限制)
\begin{filecontents*}{\jobname.bib}
@misc{myarticle,
author = {ABC},
title = {A Title},
year = {2023},
}
\end{filecontents*}
\documentclass{article}
\usepackage[algo2e,linesnumbered,algonl]{algorithm2e}
\usepackage[backref=section]{hyperref}
\newtheorem{theorem}{Theorem}
\renewcommand{\thetheorem}{!!!\arabic{theorem}!!!}% very distinctive
\makeatletter
\NewCommandCopy{\original@cite}{\cite}
\RenewDocumentCommand{\cite}{om}{%
\begingroup
\restore@sectional@label
\IfNoValueTF{#1}{\original@cite{#2}}{\original@cite[#1]{#2}}%
\endgroup
}
\newcommand{\restore@sectional@label}{%
\protected@edef\@currentlabel{%
\ifnum\value{subsubsection}>0 \thesubsubsection\else
\ifnum\value{subsection}>0 \thesubsection\else
\thesection\fi\fi
}%
}
\makeatother
\begin{document}
\section{Test}
\cite{myarticle}
\subsection{Test}
\cite{myarticle}
\subsubsection{Test}
\cite{myarticle}
% comment/uncomment the algorithm
\begin{algorithm2e}
$a=b$\;
$b=c$\;
$c=d$\;
\end{algorithm2e}
\paragraph{Test}
\cite{myarticle}
\begin{theorem}Citing~\cite{myarticle}.\end{theorem}
\bibliographystyle{plain}
\bibliography{\jobname}
\end{document}