我遇到了一个问题algorithm2e
。我想在文本中引用一个块(例如 for 循环)的结尾。因此,我在 for 语句的右括号后面放置了一个标签。当我配置该包以生成“结束”行时,标签会正确指向此行。但如果我使用选项“noend”,标签会指向 for 语句而不是 for 循环的最后一行。以下是示例:
\documentclass[]{scrartcl}
\usepackage[algo2e, noline]{algorithm2e}
\begin{document}
\begin{algorithm2e}
\For {...} { a = b\; }\label{x}
\end{algorithm2e}
Reference: \ref{x}
\end{document}
输出看起来可能会像这样:
1 为...做
2 a=b
3结束
参考文献:3
当我在文本中引用标签 x 时,我得到了对第 3 行的正确引用。
使用 package 的 noend 选项algorithm2e
,我得到以下输出:
1 为...做
2 a=b
参考文献:1
标签 x 现在创建对第 1 行而不是第 2 行的引用。
我猜这取决于 latex 如何处理标签。我可以通过将标签放在 for 循环的最后一行后面来解决这个问题。但是当我想再次显示“结束”行时,标签会指向第 2 行而不是第 3 行。
是否有可能始终生成正确的参考,而与我使用的选项无关?
答案1
您肯定触发了 中的错误algorithm2e
。虽然手册对此没有讲清楚,但我猜测end
版本的行为是正确的,并且标签应该引用块的最后一行。出现此错误的原因是\label
拾取\@currentlabel
,但algorithm2e
使用其自己的计数器AlgoLine
,并且并非\@currentlabel
在所有情况下都会将其推送到 。有趣的是 ,在加载algorithm2e
时具有用于标签处理的特殊代码hyperref
,然后一切都正常工作。因此,您的解决方法是:1. 将此错误告知 的维护者algorithm2e
。2a. 使用hyperref
包。2b. 如果您不想使用hyperref
,则以下代码定义了一个新的标签命令 ,\elabel
它可以按预期工作:
\documentclass{article}
\usepackage[lined,linesnumbered,noend]{algorithm2e}
\usepackage{hyperref}
\makeatletter
\@ifpackageloaded{hyperref}{%
\def\elabel#1{\label{#1}}%
}{%
\def\elabel#1{\@bsphack \protected@write \@auxout {}{\string \newlabel {#1}{{\theAlgoLine }{\thepage }}}\@esphack}%
}
\makeatother
\begin{document}
\SetAlgoShortEnd%
\begin{algorithm}%
\For {...} { a = b\; } \label{ya}\elabel{ya2}
\end{algorithm}%
\textbackslash{}label gives \ref{ya}, \textbackslash{}elabel is \ref{ya2}%
\SetAlgoNoEnd%
\begin{algorithm}%
\For {...} { a = b }\label{xa}\elabel{xa2}
\end{algorithm}%
\textbackslash{}label is \ref{xa}, \textbackslash{}elabel is \ref{xa2}%
\end{document}
答案2
我认为,在不干扰软件包内部运作的情况下,最简单的做法就是}
根据end
样式在之前或之后制作标签。您可以定义一个\label
不执行任何操作的变体,或者根据选项集制作标签。
\documentclass[]{scrartcl}
\usepackage[algo2e,noend,linesnumbered]{algorithm2e}
\newcommand\Aendlabel[1]{\ifthenelse{\boolean{algocf@optnoend}}{}{\label{#1}}}
\newcommand\Anoendlabel[1]{\ifthenelse{\boolean{algocf@optnoend}}{\label{#1}}{}}
\begin{document}
\begin{algorithm2e}
\For {...} { a = b\; \Anoendlabel{x}}\Aendlabel{x}
\end{algorithm2e}
Reference: \ref{x}
\end{document}
删除该noend
选项,您将获得:
\documentclass[]{scrartcl}
\usepackage[algo2e,linesnumbered]{algorithm2e}
\newcommand\Aendlabel[1]{\ifthenelse{\boolean{algocf@optnoend}}{}{\label{#1}}}
\newcommand\Anoendlabel[1]{\ifthenelse{\boolean{algocf@optnoend}}{\label{#1}}{}}
\begin{document}
\begin{algorithm2e}
\For {...} { a = b\; \Anoendlabel{x}}\Aendlabel{x}
\end{algorithm2e}
Reference: \ref{x}
\end{document}