12

I am referencing some sections (actually those will be custom defined in the end) by number, type and name. But it happens that there is no name. So I want to leave it out. How can I test for that?

A MWE:

\documentclass{article}

\usepackage{xcolor}
\definecolor{darkred}{rgb}{0.5,0,0}
\usepackage[colorlinks, linkcolor=darkred]{hyperref}
\newcommand\doubleref[1]{\autoref{#1} (\nameref{#1})}

\begin{document}

\section{This and That about Everything}\label{sec:thisthat}
    Some text.

\section{}\label{sec:two}
    Like meantioned in \doubleref{sec:thisthat} and \doubleref{sec:two}.

\end{document}

So in this example the second reference should automatically only be section 2 and not section 2 ().

I tried

\newcommand\doubleref[1]{\autoref{#1}\edef\nae@tmp{\nameref{#1}}\ifx\empty\name@tmp\relax\else\ (\name@tmp)\fi}

but \nameref does not seem to return an expandable version of the name.

12

When you say \label{x}, LaTeX stores the data in a macro called \r@x; the title (available when using hyperref) is the third of five token lists. In your case we want to test whether the title is empty, which means that the relevant token list contains only \relax, that hyperref always appends to the title.

\documentclass{article}

\usepackage{xcolor}
\definecolor{darkred}{rgb}{0.5,0,0}
\usepackage[colorlinks, linkcolor=darkred]{hyperref}

\makeatletter
\long\def\cana@extract#1#2#3#4#5{\unexpanded{#3}}
\def\cana@relax{\relax}
\newcommand\doubleref[1]{\autoref{#1}%
  \@ifundefined{r@#1}\relax{\edef\cana@temp{%
    \expandafter\expandafter\expandafter\cana@extract\csname r@#1\endcsname}%
    \ifx\cana@temp\cana@relax\else~(\nameref{#1})\fi}}
\makeatother

\begin{document}

\section{This and That about Everything}\label{sec:thisthat}
    Some text.

\section{}\label{sec:two}
    Like meantioned in \doubleref{sec:thisthat} and \doubleref{sec:two}.



\end{document}

I use \edef, but protecting the title with \unexpanded, so that it won't be expanded completely, which could cause big problems. This is tested only when the macro associated to the label has already been read in from the .aux file.

UPDATE

With a more recent LaTeX kernel, the code above no longer works, due to changes in the internal management of cross references.

\documentclass{article}

\usepackage{xcolor}
\definecolor{darkred}{rgb}{0.5,0,0}
\usepackage[colorlinks, linkcolor=darkred]{hyperref}

\makeatletter
\long\def\cana@extract#1#2#3#4#5{\unexpanded{#3}}
\newcommand\doubleref[1]{\autoref{#1}%
  \@ifundefined{r@#1}{\relax}{%
    \edef\cana@temp{%
      \expandafter\expandafter\expandafter\cana@extract\csname r@#1\endcsname
    }%
    \ifx\cana@temp\@empty\else~(\nameref{#1})\fi}}
\makeatother

\begin{document}

\section{This and That about Everything}\label{sec:thisthat}
    Some text.

\section{}\label{sec:two}
    Like meantioned in \doubleref{sec:thisthat} and \doubleref{sec:two}.

\end{document}
8
  • For whatever reason, this doesn't work for me while Heiko's solution does. I have no clue why.
    – Piotr
    Mar 2 at 14:32
  • @Piotr well, almost nine years passed since the answer was given. Why not asking before downvoting?
    – egreg
    Mar 2 at 14:35
  • 1
    @Piotr I posted an updated version
    – egreg
    Mar 2 at 19:53
  • Thanks, it works! I didn't expect such an old post to be fixed so I just wanted to push the working solution up. Also, I thought it's not a big deal - if an update comes, I can reverse the downvote and instead upvote this.
    – Piotr
    Mar 2 at 22:34
  • Actually, it compiles and seems to work but I get an error: ! Undefined control sequence. <argument> \edef \cana@temp.
    – Piotr
    Mar 2 at 22:37
7

Reimplementation of Gregorio's solution using package refcount. \getrefbykeydefault{#1}{name}{} extracts the nameref part of the reference #1. The command is full expandable. If there is not a name, then the test becomes \if\vcenter\vcenter. Otherwise the name expands to something non-expandable that differ from \vcenter. Instead of \vcenter also other non-expandable tokens can be used, it should be a token that does not occur at the start of a name.

\documentclass{article}

\usepackage{xcolor}
\definecolor{darkred}{rgb}{0.5,0,0}
\usepackage[colorlinks, linkcolor=darkred]{hyperref}

\usepackage{refcount}
\newcommand*{\doubleref}[1]{%
  \autoref{#1}%
  \if\vcenter\getrefbykeydefault{#1}{name}{}\vcenter
  \else
    ~(\nameref{#1})%
  \fi
}

\begin{document}

\section{This and That about Everything}\label{sec:thisthat}
    Some text.

\section{}\label{sec:two}
    Like meantioned in \doubleref{sec:thisthat} and \doubleref{sec:two}.

\end{document}

A variation, where the whole expression is made into a link:

\newcommand*{\doubleref}[1]{%
  \hyperref[{#1}]{%
    \autoref*{#1}%
    \if\vcenter\getrefbykeydefault{#1}{name}{}\vcenter
    \else
      ~(\nameref*{#1})%
    \fi
  }%
}

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.