4

I would like to use references in a way that an arrow is in front of the referenc and points in the direction depending on whether the referenced instance is a above or below the reference (→ chapter 5).

Using this answer I came up with the following solution.

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

While this seems to work and produces the desired result, I'm wondering whether there isn't a more elegant solution with an existing package (neither 'varioref' nor 'cleveref' seem to do the trick).

EDIT: I'd prefer a solution where I don't need to use two different kind of labels depending on the referencing style I use. I hesitate to redefine the \label command though.

0

Please let me know if this doesn't answer your question, or if it doesn't suit your need (and I will remove it). You say you hesitate to redefine \label, but there is a compromise solution, in which \label is, technically, redefined, but (hopefully) in a way which preserves the original character when needed.

I am referring to the notion of saving a copy of the original: \let\svlabel\label and then redefining in a way which uses the saved original plus does a little extra innocuous stuff that doesn't break anything else.

Here's what I propose:

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

In this way, one uses the familiar \label and \cref in the document (you could make it \ref if you preferred). When you used a style that didn't use this arrow scheme, just remove the redefinitions. The one side effect is that all \cref invocations will produce this arrow scheme (i.e., for figures, equations, and tables, not just sections). But if your goal was to avoid that for these non-section entities, then you are back to the notion of having two separate commands, depending on the \cref type.

Also, while redefining \label produced no ill effects when using it for other labeling entities, redefining the \cref did produce undefined label warnings, even though the output appears to be correct.

If you don't like all the particulars of this approach, you also have the option of redefining just the usage of \label, but leaving \where as a separate command. That would avoid the undefined label warnings, would allow the use of a single \label command, but would require two types of references, with or without arrow.

Finally, you could make your \here and \where just print an arrow, without the associated \label and \cref. It would make your document syntax a bit longer, but would allow you to define \here and \where as {} when you wanted to turn them off, without affecting the rest of the document.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.