自动切换引用中的箭头

自动切换引用中的箭头

我希望以这样一种方式使用引用,即在引用前面有一个箭头,并且指向的方向取决于引用实例是在引用的上方还是下方(→第 5 章)。

使用这个答案我想到了以下解决方案。

\documentclass{scrbook}
\usepackage{cleveref}
\makeatletter
\newcount\here@undef
\newcommand{\here}[1]{%
  \@ifundefined{here@#1@undef}{}{\advance\here@undef by -1}%
  \@namedef{here@#1}{}
  \label{#1}}
\newcommand{\where}[1]{%
  \@ifundefined{here@#1}{%
    $\rightarrow$~\cref{#1}%
    \@ifundefined{here@#1@undef}{%
      \@namedef{here@#1@undef}{}%
      \advance\here@undef by 1
    }{}%
  }{%
    $\leftarrow$~\cref{#1}%
  }%
}
\AtEndDocument{%
  \ifnum\here@undef>0
    \GenericWarning{}{There were undefined above/below labels}%
  \fi}
\makeatother

\begin{document}
\chapter{one}
As we will see (\where{chap:one}).

\chapter{two}\here{chap:one}
This is some text. 

\chapter{three}
As we have seen (\where{chap:one})

\end{document}

虽然这似乎有效并产生了预期的结果,但我想知道是否没有使用现有包的更优雅的解决方案(“varioref”和“cleveref”似乎都无法解决问题)。

编辑:我更喜欢一种解决方案,即我不需要根据我使用的引用样式使用两种不同类型的标签。\label不过,我犹豫是否要重新定义该命令。

答案1

如果这不能回答您的问题,或者不能满足您的需要,请告诉我(我会删除它)。您说您犹豫是否要重新定义\label,但有一个折衷的解决方案,即从\label技术上讲重新定义,但(希望)在需要时保留原始特征。

我指的是保存原始副本的概念:\let\svlabel\label然后以使用已保存的原始副本的方式重新定义,并做一些不会破坏其他任何东西的额外无害的事情。

以下是我的建议:

\documentclass{scrbook}
\usepackage{cleveref}
\makeatletter
\newcount\here@undef
\let\svlabel\label
\let\svcref\cref
\renewcommand{\label}[1]{%
  \@ifundefined{here@#1@undef}{}{\advance\here@undef by -1}%
  \@namedef{here@#1}{}
  \svlabel{#1}}
\renewcommand{\cref}[1]{%
  \@ifundefined{here@#1}{%
    $\rightarrow$~\svcref{#1}%
    \@ifundefined{here@#1@undef}{%
      \@namedef{here@#1@undef}{}%
      \advance\here@undef by 1
    }{}%
  }{%
    $\leftarrow$~\svcref{#1}%
  }%
}
\AtEndDocument{%
  \ifnum\here@undef>0
    \GenericWarning{}{There were undefined above/below labels}%
  \fi}
\makeatother

\begin{document}
\chapter{one}
As we will see (\cref{chap:one}).

\chapter{two}\label{chap:one}
This is some text. 

\chapter{three}
As we have seen (\cref{chap:one})

\begin{table}
\begin{center}Table\caption{Caption\label{tb:one}}\end{center}
\end{table}

In \svcref{tb:one} using original \verb|\svcref| and in
\cref{tb:one} using the revised \verb|\cref|.

Output is correct, though redefined \verb|\cref| of table generates
undefined labels.

\end{document}

这样,人们就可以在文档中使用熟悉的\labeland (如果您愿意,也可以这样做)。当您使用不使用此箭头方案的样式时,只需删除重新定义即可。一个副作用是\cref\ref全部 \cref调用将产生这种箭头方案(即,用于图形、方程式和表格,而不仅仅是章节)。但如果您的目标是避免这些非章节实体出现这种情况,那么您将回到根据类型使用两个单独命令的概念\cref

此外,虽然重新定义\label在用于其他标签实体时不会产生不良影响,但重新定义确实\cref会产生未定义的标签警告,即使输出看起来是正确的。

如果您不喜欢此方法的所有细节,您也可以选择重新定义 的使用\label,但将其保留\where为单独的命令。这样可以避免未定义标签警告,允许使用单个\label命令,但需要两种类型的引用,带箭头或不带箭头。

最后,您可以让\hereand\where只打印一个箭头,而不使用关联的\labeland \cref。这样会使您的文档语法更长一些,但可以让您在想要关闭它们时定义 and ,而不会影响文档的其余部分\here\where{}

相关内容