3

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?

  • @ChristianHupfer Ok. I adjusted the question. I hope it is clear. See code comment updates too. – Jonathan Komar Sep 22 '15 at 6:41
  • No, sorry. Should the mymacro label refer to Fruit??? – user31729 Sep 22 '15 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 '15 at 6:44
  • @yo' Thanks for catching that slip, I will fix that immediately. – Jonathan Komar Sep 22 '15 at 6:45
  • @macmadness86: The \label command uses the last counter being used in refstepcounter – user31729 Sep 22 '15 at 6:45
4

\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.

  • 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/… – Jonathan Komar Sep 22 '15 at 8:15
  • Could you please explain why the expansion of the argument for the \menu{} macro works, but not for the \texttt{} macro? – Jonathan Komar Sep 22 '15 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 '15 at 12:14

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.