6

I have an article class document with a structure like this.

  • Part A
    • Section 1
    • Section 2
  • Part B
    • Section 1
    • Section 2

I want to reference Section 1 in part A from Section 2 in part B. When I reference a section in another part using \ref, \vref or \cref I get

As seen in Section 1.

Since that appears in Part B, the reader would assume I'm talking about section 1 in part B, but I mean section 1 in part A.

Desired output:

As seen in Section 1 in Part A.

Now comes the tricky part. Most of my references are for within the same section. If I'm in Part B and I'm referencing something in Part B, I just want to say

As seen in Section 1

Not

As seen in Section 1 in Part B

Is there some combination of varioref,hyperref, cleveref and whatever else which can do that with a single command? (Bonus points if it is hyperlinked and can include smart page numbers like \vref)

I suppose redefining section numbers to be of the form A.1 would work. Is there a way of doing it without that?

MWE

\documentclass[a4paper]{article}

\usepackage[english]{babel} %do I need this? Gummi throws an error if I leave it out. I dunno.
\usepackage{varioref}
\usepackage[hidelinks]{hyperref}
\usepackage[nameinlink, capitalise, noabbrev]{cleveref}


\begin{document}

\part{First Part}\label{sec:first part}

\section{section in first part}\label{sec:in first part}

\part{Second Part}\label{sec:second part}

\section{section in second part}\label{sec:in second part}

\Cref{sec:in first part} is cool
%desired output: Section 1 in Part A is cool.


\Cref{sec:in second part} is also cool.
%desired output: Section 1 is also cool.

\end{document}

Edit: The penultimate line is supposed to say 'this part' not 'another part'. Disambiguated the reference sentences.

  • 3
    I don't recommend spaces in the label name – user31729 May 29 '16 at 10:47
  • 1
    Why? I've never had any troubles using spaces in labels. – falsePockets May 29 '16 at 10:57
  • There might be cases when the label name has to be processed further, the spaces make this is a little bit trickier. – user31729 May 29 '16 at 11:00
4

Since there is no direct information about section of which part in the standard \LaTeX reference system the solution of such a 'context' aware referencing is involved with a lot of ugly hacks...

... if one uses the standard reference system ;-)

However, with Heiko Oberdiek's zref package and the help of cleveref this job can be done with less hacking.

The key is to write additional data as label - meta information such as counter name, part value, section value (called properties) etc with a \zref@labelbyprops to the .aux file and retrieving the relevant information with \zref@extract (which is expandable, fortunately!)

The cleveref package is not really needed here, but it's nice to exploit its \crefname features by using the macros \cref@<type>@name etc. macros once the counter type is known.

Please note that the new macro \zclabel is needed, instead of the traditional \label macro.

\documentclass{article}

\usepackage[counter,user,hyperref]{zref}

\makeatletter
\AtBeginDocument{%
\@ifpackageloaded{hyperref}{%
}{
  \providecommand{\phantomsection}{}
  \providecommand{\hyperlink}[2]{#2}
}

\zref@newlist{sectionprop}
\zref@newprop{partinfo}[-1]{\thepart}
\zref@newprop{sectioninfo}[-1]{\number\value{section}}

\newcommand{\zclabel}[1]{%
  \zref@labelbyprops{#1}{partinfo,sectioninfo,anchor,counter}%
}

% Wrapper macros that extract the reference counter type and the reference value -- this way, no additional \label is necessary

\newcommand{\countercref}[1]{%
  \expandafter\csname cref@\zref@extract{#1}{counter}@name\endcsname\ \hyperlink{\zref@extract{#1}{anchor}}{\zref@extract{#1}{sectioninfo}}%
}

\newcommand{\Countercref}[1]{%
  \expandafter\csname Cref@\zref@extract{#1}{counter}@name\endcsname\ \hyperlink{\zref@extract{#1}{anchor}}{\zref@extract{#1}{sectioninfo}}%
}


\newcommand{\secref}[1]{%
  % Check first whether the label is defined at all, otherwise \Countercref etc. would fail!
  \zref@ifrefundefined{#1}{}{% 
    % Preexpand some information
    \edef\@tmp@a{\zref@extract{#1}{partinfo}}%
    \edef\@tmp@b{\thepart}%
    \ifx\@tmp@b\@tmp@a\relax% Compare \thepart with the result of the zref - label - value for par
    \Countercref{#1} in this \partname%
    \else
    \Countercref{#1} in \partname\ \zref@extract{#1}{partinfo}%
    \fi
  }%
}

}
\makeatother


\usepackage{hyperref}
\usepackage{cleveref}

\renewcommand{\thepart}{\Alph{part}}

\begin{document}
\part{First Part}
\section{section in first part}\zclabel{sec:infirstpart}
\part{Second Part}
\section{section in second part}\zclabel{sec:insecondpart}
\secref{sec:infirstpart} is cool and \secref{sec:insecondpart} is cool too, but \secref{sec:inthirdpart} is even better!
\part{Third Part}
\section{section in third part}\zclabel{sec:inthirdpart}


\end{document}

enter image description here

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.