39

(Repost from Stack Overflow)

I'd like to refer to a description list item by name instead of number. To that effect, I've added labels to each item, but when referencing them I only get the name of the section, not of the list item. How can I change it to show a custom label for each item?

\section{Definitions}
\begin{description}
    \item [Vehicle\label{itm:vehicle}] Something
    \item [Bus\label{itm:bus}] A type of \nameref{itm:vehicle}
    \item [Car\label{itm:car}] A type of \nameref{itm:vehicle} smaller than a \nameref{itm:bus}
\end{description}

The result is something like this:

1 Definitions

Vehicle Something
Bus A type of Definitions
Car A type of Definitions smaller than a Definitions

I'd like to have the following:

1 Definitions

Vehicle Something
Bus A type of Vehicle
Car A type of Vehicle smaller than a Bus

An alternative solution would be to use subsections and display them as a definition list. Anyone know how to do it?

The best answer on Stack Overflow referenced a \makeatletter hack:

\makeatletter
\def\namedlabel#1#2{\begingroup
   \def\@currentlabel{#2}%
   \label{#1}\endgroup
}
\makeatother
...
\section{Definitions}
\begin{description}
    \item [Vehicle\namedlabel{itm:vehicle}{Vehicle}] Something
    \item [Bus\namedlabel{itm:bus}{Bus}] A type of \ref{itm:vehicle}
    \item [Car\namedlabel{itm:car}{Car}] A type of \ref{itm:vehicle} smaller than a \ref{itm:bus}
\end{description}

It works, with the caveat that the links lead back to the section header, not to the list item. It would be nice to use something native which doesn't break \ref.

3 Answers 3

35

To expand a bit on some of the other answers: here is a modification that does not change the syntax of the description environment:

\documentclass{article}
\usepackage{hyperref}
\usepackage{nameref}

\makeatletter
\let\orgdescriptionlabel\descriptionlabel
\renewcommand*{\descriptionlabel}[1]{%
  \let\orglabel\label
  \let\label\@gobble
  \phantomsection
  \edef\@currentlabel{#1}%
  %\edef\@currentlabelname{#1}%
  \let\label\orglabel
  \orgdescriptionlabel{#1}%
}
\makeatother

\begin{document}

\section{Definitions}
\begin{description}
    \item [Vehicle\label{itm:vehicle}] Something
    \item [Bus\label{itm:bus}] A type of \ref{itm:vehicle}
    \item [Car\label{itm:car}] A type of \ref{itm:vehicle} smaller than a \ref{itm:bus}
\end{description} 

The item `\ref{itm:bus}' is listed on page~\pageref{itm:bus} in section~\nameref{itm:bus}.

\end{document}
5
  • Excellent stuff; now \ref even works like expected outside of the description environment.
    – l0b0
    Aug 10, 2010 at 12:44
  • 2
    @Martin Heller @Andrew Stacey Do you know if it is possible to have the references in spacedlowsmallcaps font? I am using classicthesis, where description items are written using this font (the code from the style file: \renewcommand{\descriptionlabel}[1]{\hspace*{\labelsep}\spacedlowsmallcaps{#1}}‌​), so when I am referencing the items I would like them to look the same as in the list.
    – Elena
    Nov 20, 2013 at 15:45
  • 1
    @MartinHeller Your code works nice in my minimal test. In one of my larger documents, I get this error: ! Use of \\smash doesn't match its definition. Sep 21, 2015 at 13:06
  • @MartinHeller Apparently your code has an error when the item itself contains expandable material. See tex.stackexchange.com/questions/268842/… for a solution. Great work though! This is a wonderful capability. Sep 22, 2015 at 8:34
  • 10
    Just a small remark: I had to slightly modify this solution and use \edef\@currentlabel{#1\unskip}% instead of just \edef\@currentlabel{#1}% to prevent the appearance of extra space to the right of the text inside the hyperlinks produced by \ref{}.
    – cgogolin
    Aug 19, 2017 at 12:08
12

Here's a version that seems to work. There are, I think, two separate issues with what you are trying to do. One is simply to get the labels to be what you want and not according to some automatic numbering scheme. That's what the SO hack does. The other issue is to ensure that these labels refer to what you think that they are referring to. The SO hack does not address this. The point is that a label is both a label and a marker. In normal TeX, this dual role isn't visible because the marker isn't really used (well, it's used to figure out what the label should contain, but you want to override that). But when using a hyperlink package, such as hyperref.sty, the marker means something again: it's where the hyperlink goes to.

So you need to both change the label and have the marker at the right point. The former is solved by the SO hack, but the latter (as I said) is not. Either you can add the markers in explicitly, or you can subvert something that would put them in automatically. The reason they aren't there is that you are using the description environment which doesn't automatically put in the markers. By using a different listing environment, say enumerate, which does get the markers put in, we can get the desired behaviour. It's still a "hack", I'm afraid, but not a very big one.

The following does it, as far as my testing shows:

\documentclass{article}
\usepackage{hyperref}

\makeatletter
\newcommand{\labitem}[2]{%
\def\@itemlabel{\textbf{#1}}
\item
\def\@currentlabel{#1}\label{#2}}
\makeatother

\begin{document}
\begin{enumerate}
\labitem{Vehicle}{itm:vehicle} Something
\labitem{Bus}{itm:bus} A type of \ref{itm:vehicle}
\labitem{Car}{itm:car} A type of \ref{itm:vehicle} smaller than a \ref{itm:bus}
\end{enumerate}

Let's refer to \ref{itm:vehicle} \ref{itm:bus} and \ref{itm:car}

\end{document}
1
  • 1
    This may not behave correctly i have indentation problems when I use it
    – Mr. D
    May 24, 2016 at 8:59
5

Following up on the second suggesiton, assuming you're using hyperref, you could change the definition to:

\makeatletter
\def\namedlabel#1#2{\begingroup
   \def\@currentlabel{#2}%
   \phantomsection\label{#1}\endgroup
}
\makeatother

The phantomsection should anchor backreference links to the item.

There might be a way to do this using the enumitem package too, but I'd have to look further into it.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .