我如何重新定义当前标签?

我如何重新定义当前标签?

我在使用算法时遇到了反向引用问题。

考虑以下示例

\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}

在此处输入图片描述

相关内容