Relative chapter references

(A follow-up of sorts on Variable chapter references, as per @werner 's suggestion)

This is somewhere in between a request for comments and an actual question (as well as a summary of my experiences whilst trying to implement the linked question's idea to my personal liking, I hope someone else finds it helpful too).

The idea is (in the same spirit as the varioref package) to avoid redundancy and awkwardness whilst (hyper)referencing.

So, suppose you have a (hyper)reference to chapter 4 from within chapter 5, I'd like that to come out as (a linked up) "the next chapter" rather than "chapter 5 on page XX" (italics added for emphasis), analogously if you're referencing chapter 3 from within chapter 4.

Likewise, I'd like this mechanism to work for sections, subsections, etc. all the way down to subparagraphs.

An initial solution

An initial (ie. considering \chapters alone) solution to the problem was posted in the linked question above, and it basically boils down to:

\usepackage{hyperref}
\usepackage{smartref}
\usepackage{cleveref}

\usepackage{xifthen}

\newcounter{actualchap}

\newcommand{\relref}[1]{
\sgetchapterval{\targetchap}{#1}% Retrieve chapter counter from reference
\setcounter{actualchap}{\value{chapter}}
\ifthenelse{\equal{\targetchap}{\theactualchap}}%
{\hyperref[#1]{the next chapter}}%
\ifthenelse{\equal{\targetchap}{\theactualchap}}%
{\hyperref[#1]{the previous chapter}}%
{\cref{#1}}%
}%
}

\crefformat{chapter}{#2chapter~#1#3}
\Crefformat{chapter}{#2Chapter~#1#3}


Note that we're using the hyperref package, the smartref package, the cleveref package, and the xifthen package.

Digression / explanation

Why do we need both smartref and cleveref? Well, because we'd like to get all of this nice functionality without sacrificing (hyper)reference customization. Every other solution I could come up with eventually ended up doing (directly or indirectly) something along the lines of:

\renewcommand*{\thechapter}{WHATEVER}


now, this breaks all of our carefully laid down smartref incantations: smartref relies on the .aux file containing untainted LaTeX references, whilst redefining \thechapter could make said entries contain LaTeX commands themselves (trying to get chapter numbers using \oldstylenums was a sure shot way of falling right into this), In other words: formatting is happening too soon! (it's present right there in the .aux file already)

If, on the other hand, we use cleverefexclusively (by using cleveref's \cref command instead of LaTeX's \ref one), we can achieve the same effect (see the \crefformat and \Crefformat commands above, see cleveref's documentation for an explanation on what the #2 and #3 parameters are and why do we need to define a capitalized and non-capitalized version of each) without ruining our other work: cleveref leaves laTeX's references alone, and it only applies formatting at the very end! (the second time LaTeX is run)

Question proper

So, this is pretty sweet, but still, there's room for improvement (and my TeXnical skills are pretty much nonexistent besides some debugging and .aux file digging):

1. I'd like this same mechanism to work on sections, subsections, etc. (as stated above) without having to define different commands (ie. the \relref command above should be able of discerning on its own whether the reference it's given is to a chapter, section, subsection, etc.),

2. it should work on *ed sectioning commands as well,

3. it should play along nicely with hyperref whilst doing all of this (I see no reason why this could not be so).

So... longish question indeed, wanted to share the experience gathered nevertheless.

Have I tickled your interest? :)

• I don't understand why you need smartref at all. Why not just use cleveref and \cref'? (If you *really* don't want to change all your \refs into \crefs, you can \let\ref\cref in your preamble. Though I recommend doing a search-and-replace \ref -> \cref in your source instead, to leave the original LaTeX \ref intact just in case.) Nov 21, 2013 at 15:55
• Does touhami's answer to a related question solve the issues mentioned here? Aug 22, 2015 at 20:10

About your first question, I think you should be able to use the \getreftype{..} command as defined here (\getreftype{#1} in your case) to discern the type of the reference that is the parameter of your function.

I think something like that should work :

\newcounter{actualelement}

% ... and more

\newcommand{\relref}[1]{
\csname sget\getreftype{#1}val\endcsname{\target}{#1}% Retrieve 'target' counter from reference
\setcounter{actualelement}{\value{\getreftype{#1}}}% Current 'element'
\ifthenelse{\equal{\target}{\theactualelement}}%
{\hyperref[#1]{the next \getreftype{#1}}}%
{%
\ifthenelse{\equal{\target}{\theactualelement}}%
{\hyperref[#1]{the previous \getreftype{#1}}}%
{\cref{#1}}%
}%
}

\crefformat{chapter}{#2chapter~#1#3}
\Crefformat{chapter}{#2Chapter~#1#3}
\crefformat{section}{#2section~#1#3}
\Crefformat{section}{#2Section~#1#3}
\crefformat{subsection}{#2subsection~#1#3}
\Crefformat{subsection}{#2Subsection~#1#3}


But no idea at this time for points 2 and 3 ...

• Did you test your suggestion? Feb 19, 2012 at 6:07
• Yes, I was using it a few times ago (december, I guess). But I just realised I forgot to link to the page with the macro getreftype{..} ! My bad.
– XaF
Feb 19, 2012 at 8:42
• I think you meant to link here ;)
– mpr
Feb 19, 2012 at 17:27
• @mpr you're right, I didn't remember exactly were I originally found the idea of this macro, and I have found the link I refered to in my history :)
– XaF
Feb 19, 2012 at 21:03

I know this is a very old question, but I'm screening for some known problems with cross-referencing and just found it, and I have (disclosure made) recently come up with a package which does just what you are asking for, and is actually more general, since you can do the same kind of relative reference to pages, and so on. It's called zref-check and is based on zref (so it makes use of zref labels, not the standard ones, though you can make them work together to some extent, check the docs).

And it does match all of your requirements. In particular, it works for all sections and chapter, starred or not, and uses hyperref if you load it (this is configurable).

The UI concept is somewhat different than the regular reference commands (standard or of the most common packages): instead of trying to guess what should be typeset, zref-check lets you write what you want, and provides you with an easy way to get a warning at compilation if the statement you made no longer corresponds to the actual document as typeset.

A sample document using references to sectioning labels:

\documentclass{book}

\usepackage{lipsum}

\usepackage{zref-check}

\usepackage{hyperref}

\begin{document}

\chapter{Chapter 1}
\zlabel{cha:chapter-1}

\lipsum

\zcheck{sec:section-2.1}[nextchap]{on the next chapter}

\zcheck{sec:section-1.1}[nextsec]{on the next section}

\section{Section 1.1}
\zlabel{sec:section-1.1}

\lipsum

\chapter{Chapter 2}
\zlabel{cha:chapter-2}

\lipsum

\section{Section 2.1}
\zlabel{sec:section-2.1}

\lipsum

\zcheck{sec:section-2.2}[nextsec]{on the next section}

\section{Section 2.2}
\zlabel{sec:section-2.2}

\lipsum

As discussed \zcheck{sec:section-2.1}[prevsec]{on the previous section}:
\lipsum[1]

But more of this \zcheck{cha:chapter-1}[nextchap]{on the next chapter} (this
is an incorrect reference, so you get a warning).

\end{document}
`

There is plenty more (a total of 22 defined "checks" available), but this is just making use of the kind of sectioning relations required by the OP.