5

This question is related to Reference name of description list item in LaTeX, because that is the same as what I am doing. The answer provided there works in most cases, but I found a case where it fails to label a macro properly.

Description of Problem

The normal behavior of labels is to reference last labelable thing (\autoref{} in place of \ref{} will verify this in some cases). This is not the desired effect when labeling the default item labels themselves in description lists with labels (note: terminology conflict…labels of items \item [label] Text. and labeling the item labels \item [label\label{mylabel}] Text.*). Therefore, we need to redefine items for description lists. The question mentioned above does this.

When using labels within description lists, a \phantomsection needs to be added for the labels to label :). Makes sense so far to me. I'd like to know why the code fails below (see notes in code).

Purpose

I am describing many lists of parameters and oftentimes, the parameters for one function have already been described elsewhere. Cross-references are then extremely convenient.

Code

\documentclass{article}
\usepackage{fontspec} % xelatex ext font support
\usepackage{enumitem} % Add easy custom list support
\usepackage{menukeys} % Demonstrate labeling of macros
\usepackage{hyperref} % Add ref support
\setlength\parindent{0pt} % Globally set indentation for new paragraphs
\setlist[description]{style=nextline,labelwidth=0pt,leftmargin=30pt,itemindent=\dimexpr-20pt-\labelsep\relax} % Global Setup Description List

\newcommand{\mymacro}[1]{\texttt{#1}} % my custom macro

\makeatletter % Redefinition of Description List Items source: https://tex.stackexchange.com/a/1248/13552
\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{Labels}
\label{mymacro} %<-- This works (comment this out when testing my problem)
\begin{description}
\item [Fruit] The is a fruit. A plain item.
\item [\menu{Vegetables}\label{menukeysmacro}] This is a vegetable. Macro from the \texttt{menukeys} package.
%\item [\mymacro{Meat}\label{mymacro}] This is some meat. Custom macro. % <-- This does not work (This should label \mymacro{Meat})
\end{description}

\section{References}    
This is a menukeysmacro \ref{menukeysmacro} for fun. 

Now we reference the mymacro \ref{mymacro}.
\end{document}

Output

enter image description here

Problematic Code (just code above with the appropriate things uncommented)

\documentclass{article}
\usepackage{fontspec} % xelatex ext font support
\usepackage{enumitem} % Add easy custom list support
\usepackage{menukeys} % Demonstrate labeling of macros
\usepackage{hyperref} % Add ref support
\setlength\parindent{0pt} % Globally set indentation for new paragraphs
\setlist[description]{style=nextline,labelwidth=0pt,leftmargin=30pt,itemindent=\dimexpr-20pt-\labelsep\relax} % Global Setup Description List

\newcommand{\mymacro}[1]{\texttt{#1}} % my custom macro

\makeatletter % Redefinition of Description List Items source: https://tex.stackexchange.com/a/1248/13552
\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{Labels}
\begin{description}
\item [Fruit] The is a fruit. A plain item.
\item [\menu{Vegetables}\label{menukeysmacro}] This is a vegetable. Macro from the \texttt{menukeys} package.
\item [\mymacro{Meat}\label{mymacro}] This is some meat. Custom macro. % <-- This does not work (This should label \mymacro{Meat})
\end{description}

\section{References}    
This is a menukeysmacro \ref{menukeysmacro} for fun. 

Now we reference the mymacro \ref{mymacro}.
\end{document}

Update: This question has some follow-up question to be found here: How can I use hyperref hyperlinks inside of description list keys?

8
  • @ChristianHupfer Ok. I adjusted the question. I hope it is clear. See code comment updates too. Sep 22, 2015 at 6:41
  • No, sorry. Should the mymacro label refer to Fruit???
    – user31729
    Sep 22, 2015 at 6:43
  • 1
    Your statement about "labels refering to the last section" is wrong. When you place a \label, it refers to the last thing that was said to be "labelable".
    – yo'
    Sep 22, 2015 at 6:44
  • @yo' Thanks for catching that slip, I will fix that immediately. Sep 22, 2015 at 6:45
  • @macmadness86: The \label command uses the last counter being used in refstepcounter
    – user31729
    Sep 22, 2015 at 6:45

1 Answer 1

6

\edef\@currentlabel{#1} must be replaced by \protected@edef\@currentlabel{#1} otherwise the expansion of the argument fails.

\documentclass{article}
\usepackage{fontspec} % xelatex ext font support
\usepackage{enumitem} % Add easy custom list support
\usepackage{menukeys} % Demonstrate labeling of macros
\usepackage{hyperref} % Add ref support
\setlength\parindent{0pt} % Globally set indentation for new paragraphs
\setlist[description]{style=nextline,labelwidth=0pt,leftmargin=30pt,itemindent=\dimexpr-20pt-\labelsep\relax} % Global Setup Description List

\newcommand{\mymacro}[1]{\texttt{#1}} % my custom macro

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


\begin{document}

\section{Labels}
%\label{mymacro} %<-- This works (creates reference to Label)
\begin{description}
\item [\menu{Fruit}] The is a fruit. A plain item.
\item [\menu{Vegetables}\label{menukey::Vegetables}] This is a vegetable. Macro from the \texttt{menukeys} package.
\item [\mymacro{Meat}\label{mymacro}] This is some meat. Custom macro. % <-- This does not work (comment out other mymacro label)
\end{description}

\section{References}    
This is a menukeysmacro \ref{menukey::Vegetables} for fun. 

Now we reference the mymacro \ref{mymacro}
\end{document}

enter image description here

Edit

The real culprit is that \texttt as most (or all?) \text... style macros are (highly) fragile.

An alternative (without using \protected@edef) would be to make the \texttt{} command robust (Package etoolbox is needed for this)

\robustify\texttt

But this procedure will become tedious if other fragile commands will appear in \mymacro. So \protected@edef is perhaps the better way.

3
  • Now you know why the original question title contained the word "robust" :) Thanks. I thought there was some trick to make it self-protecting as explained: tex.stackexchange.com/questions/4736/… Sep 22, 2015 at 8:15
  • Could you please explain why the expansion of the argument for the \menu{} macro works, but not for the \texttt{} macro? Sep 22, 2015 at 8:32
  • 1
    @macmadness86: sorry, I was in lectures and could not answer immediately. I assume, that \texttt{...} is the usual culprit, i.e. it's fragile
    – user31729
    Sep 22, 2015 at 12:14

You must log in to answer this question.

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