2

Aim

I want to be able to label and then reference items in description environments created using the enumitem package.

What does not work

The following example modifies the accepted answer at How can I label / reference description items that contain macros by name?.

\documentclass[12pt]{article}

\usepackage[colorlinks=true,linkcolor=red]{hyperref}
\usepackage[nameinlink,noabbrev,capitalize]{cleveref}
\usepackage{enumitem}

\newlist{describe}{description}{1}
\setlist[describe,1]{%
  font=\normalfont\textsf,
  itemindent=0pt,
  wide,
  itemsep=0pt,topsep=2pt,
}

% Redefine Description List Items 
%    (source: http://tex.stackexchange.com/a/1248/13552)
\makeatletter
\let\orgdescriptionlabel\descriptionlabel
\renewcommand*{\descriptionlabel}[1]{%
  \let\orglabel\label
  \let\label\@gobble
  \phantomsection
  \protected@edef\@currentlabel{#1}%
  \let\label\orglabel
  \orgdescriptionlabel{#1}%
}
\makeatother

\begin{document}

\Large
\section{Good eats}

\begin{describe}

\item [Fruit:] Oranges and apples.
\item [Vegetable:\label{item:veggie}] Kale and potatoes. 

\end{describe}

\newpage 
Refer to \ref{item:veggie} above on \cpageref{item:veggie}.

\end{document}

Output:

Faulty item reference

There are three defects with this output:

  1. The face of the reference is the same sans-serif as the label itself, but I want normalfont to match the surrounding text.
  2. There is superfluous punctuation (:) in the reference, but I want just the name of the item and not any trailing punctuation. (Note that for different describe environments, the trailing punctuation could be different, e.g., a period instead of a colon.)
  3. There is extra blank space between the reference and the text "above on ..." that follows it.

How can these defects be repaired?

What does work but uses awkward syntax

The following version of the source, based upon the accepted answer at Reference name of description list item in LaTeX, cures all three defects — but at the cost of an awkward syntax within the \item optional argument.

What I find syntactically awkward is that the optional argument to \item includes a new macro \namedlabel that takes two arguments — the label identifier and the item name — and then any punctuation has to go outside and after that 2nd argument.

\documentclass[12pt]{article}

\usepackage[colorlinks=true,linkcolor=red]{hyperref}
\usepackage[nameinlink,noabbrev,capitalize]{cleveref}
\usepackage{enumitem}

% From 
% https://tex.stackexchange.com/questions/1230/reference-name-of-description-list-item-in-latex
\makeatletter
\def\namedlabel#1#2{\begingroup
    #2%
    \def\@currentlabel{#2}%
    \phantomsection\label{#1}\endgroup
}
\makeatother

\newlist{describe}{description}{1}
\setlist[describe,1]{%
  font=\normalfont\textsf,
  itemindent=0pt,
  wide,
  itemsep=0pt,topsep=2pt,
}

\crefname{page}{page}{page}

\begin{document}
\Large
\section{Good eats}

\begin{describe}

\item[Fruit:] Oranges and apples.

% Awkward syntax in optional argument to \item below:
\item[\namedlabel{item:veggie}{Vegetable}:] Kale and potatoes.

\end{describe}

%\newpage

Refer to \ref{item:veggie} above on \cpageref{item:veggie}.

\end{document}

Output: OK output but awkward syntax

  • 2
    Why is the working solution an awkward syntax? You probably don't want to include the colon (:) in the reference text, so you have to tell LaTeX, which part of the description label it should take. Use braces to delimit this part and move the label command in front of it, et voila, you are at the working solution. The main problem with your solution is that you hand everything that \descriptionlabel gets to the label command. This includes all the special formatting that you want to have in the describe environment but not when referencing it. So just go with the working solution. – gernot Apr 18 '17 at 16:02
  • 1
    @gernot: Sorry, but I don't understand whether you're saying I should try modifying the "working solution" and if so, how to do that so as to make the syntax less awkward. (I do understand that the punctuation, if it's not to be included in the reference, has to go outside the arguments to \namedlabel.) – murray Apr 18 '17 at 16:19
  • 2
    I'm just saying that you should live with the "awkward" syntax. I don't understand what's so awkward about it. I'd expect that you will always end up with a construction like this, since this is what logically is required: marking the part that should be used in references and assigning a name to it. What exactly don't you like about it? – gernot Apr 18 '17 at 16:22
2

I (like gernot in his comments to your question) see no problem with the syntax of \namedlabel. Nevertheless you can indeed define additional commands to mark parts of the item label to become not part of the reference. You can also define how automatic parts of the argument of \descriptionlabel should be interpreted while the expanding it to define the reference. And you could add a command to define which part of the argument should got to the reference. Here is an example that does automatically remove the \hfil from the reference (but not the font switch nor the :), manually removes the : or as an alternative defines the whole reference part:

\documentclass[12pt]{article}

\usepackage[colorlinks=true,linkcolor=red]{hyperref}
\usepackage[nameinlink,noabbrev,capitalize]{cleveref}
\usepackage{enumitem}

\newlist{describe}{description}{1}
\setlist[describe,1]{%
  font=\normalfont\textsf,
  itemindent=0pt,
  wide,
  itemsep=0pt,topsep=2pt,
}

% Redefine Description List Items 
%    (source: http://tex.stackexchange.com/a/1248/13552)
\makeatletter
\let\orgdescriptionlabel\descriptionlabel
\newcommand*{\@restrictlabeltext}[1]{#1\protected@edef\@currentlabel{#1}}
\newcommand*{\nolabel}[1]{#1}%
\renewcommand*{\descriptionlabel}[1]{%
  \let\orglabel\label
  \let\label\@gobble
  \let\orig@hfil\hfil
  \def\hfil{}%
  \let\nolabel\@gobble
  \let\restrictlabeltext\@firstofone
  \phantomsection
  \protected@edef\@currentlabel{#1}%
  \let\hfil\orig@hfil
  \let\label\orglabel
  \let\restrictlabeltext\@restrictlabeltext
  \orgdescriptionlabel{#1}%
}
\makeatother

\begin{document}

\Large
\section{Good eats}

\begin{describe}

\item [Fruit\nolabel{:}\label{item:fruit}] Oranges and apples.
\item [\restrictlabeltext{Vegetable}:\label{item:veggie}] Kale and potatoes. 

\end{describe}

\newpage 
Refer to \ref{item:veggie} above on \cpageref{item:veggie} or \ref{item:fruit}
on \cpageref{item:fruit}.

\end{document}

You could also make the : active and define it to be empty or \relax while the \protected@edef. You could even temporary redefine the font commands. But I don't think, that any of this suggestions are really better than your solution.


As an completely different alternative you could put the colon as part of the label format and patch \phantomsection and setting of \@currentlabel into the description list of enumitem:

\documentclass[12pt]{article}

\usepackage[colorlinks=true,linkcolor=red]{hyperref}
\usepackage[nameinlink,noabbrev,capitalize]{cleveref}
\usepackage{enumitem}
\usepackage{xpatch}

\newlist{describe}{description}{1}
\setlist[describe,1]{%
  font=\normalfont\textsf,
  itemindent=0pt,
  wide,
  itemsep=0pt,topsep=2pt,
  format={\normalfont\textsfcolor}
}
\newcommand*{\textsfcolor}[1]{\textsf{#1:}}
\makeatletter
\xpatchcmd{\enit@description@i}{%
  \labelsep\z@
}{%
  \phantomsection
  \let\org@label\label
  \let\label\@gobble
  \protected@edef\@currentlabel{##1}%
  \let\label\org@label
  \labelsep\z@
}{}{\undefined}
\makeatother

\begin{document}

\Large
\section{Good eats}

\begin{describe}

\item [Fruit\label{item:fruit}] Oranges and apples.
\item [Vegetable\label{item:veggie}] Kale and potatoes. 

\end{describe}

\newpage 
Refer to \ref{item:veggie} above on \cpageref{item:veggie} or \ref{item:fruit}
on \cpageref{item:fruit}.

\end{document}

This will result in:

enter image description here

  • I guess it's a tradeoff. I do like using an ordinary \label command, which is easier to spot in source, but of course that entrails the awkward wrapping of the item description (minus the punctuation) inside another macro, at least if I want to avoid carrying over the font of the item description to the reference. – murray Apr 18 '17 at 16:48
  • @murray: In this case you have to do something completely different. See the second part of my answer. – Schweinebacke Apr 18 '17 at 17:06
  • The 2nd part of your answer seems simplest to me. I'll just define two versions of both describe and \textsfcolor [sic] -- one using the colon as punctuation and another using a period. And perhaps a third version that uses no punctuation at all. (I suppose I could define an environment one of whose args is the particular punctuation, but that may be more trouble than it's worth, and ultimately involve more complicated expressions in the document body. – murray Apr 18 '17 at 21:18
  • I'm waiting to see if anybody comes up with a solution that is more robust in the sense that it does not involve hacking internals (with @commands). – murray Apr 19 '17 at 0:45

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.