4

I already asked a related question, How can I label / reference description items that contain macros by name?

Now I am having difficulty compiling description lists using hyperref's hyperlinks.

Problem

I'd like to make description list items (let's call each item a key-value pair) that contains hyperlinks in its keys.

Code

The description list has already been redefined once to allow label references to macros (namely the macros provided by menukeys).

\documentclass{article}
\usepackage{fontspec} % for xelatex
\usepackage{hyperref}
\usepackage{enumitem}

\setlist[description]{style=nextline,labelwidth=0pt,leftmargin=30pt,itemindent=\dimexpr-20pt-\labelsep\relax} % Global Setup Description List
    
\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
  \protected@edef\@currentlabel{#1}%
  %\edef\@currentlabelname{#1}%
  \let\label\orglabel
  \orgdescriptionlabel{#1}%
}
\makeatother

\begin{document}
\section{User Interface}
The following is a list of important user interface components:
\begin{description}
  \item [Main Window] The main window. % <-- Not so cool.
  \item [Side Bar] for navigation. % <-- Not so cool.
  \item [Document Tree] A document tree. % <-- Not so cool.
  %\item [\hyperlink{gui:mainwindow}{Main Window}] The main window. % <-- way cooler
  %\item [\hyperlink{gui:sidebar}{Side Bar}] for navigation. % <-- way cooler
  %\item [\hyperlink{gui:documenttree}{Document Tree}] A document tree. % <-- way cooler
\end{description}

\hypertarget{gui:mainwindow}{\subsection{Main Window}}
Some nice long description.

\hypertarget{gui:sidebar}{\subsection{Side Bar}}
Some nice long description.

\hypertarget{gui:documenttree}{\subsection{Document Tree}}
Some nice long description.

\end{document}
  • \protect\hyperlink, but this has to be done each time :-(, unless robustified or a (weird) redefinition of \item – user31729 Mar 3 '16 at 13:59
  • I wrapped the \hyperlinks in curly braces and it worked... (XeTeX 2.6) – Tom Jun 29 '18 at 13:56
5

\item is a command with moving (optional) argument, i.e. \hyperlink is fragile here. Either use \protect\hyperlink{...} (each time) or incorporate the \protect into\item[...]with a redefinition of\item`.

Another possibility is to use \robustify{\hyperlink} (needs etoolbox), but am unsure whether a global robustification of \hyperlink is a clever idea.

\documentclass{article}
\usepackage{fontspec} % for xelatex
\usepackage{enumitem}
\usepackage{xparse}
\usepackage{hyperref}

\setlist[description]{style=nextline,labelwidth=0pt,leftmargin=30pt,itemindent=\dimexpr-20pt-\labelsep\relax} % Global Setup Description List

\AtBeginDocument{%
\let\origitem\item

\RenewDocumentCommand{\item}{o}{%
  \IfValueTF{#1}{%
  \origitem[\protect#1]%
  }{%
    \origitem% 
  }
}
}

\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{User Interface}
The following is a list of important user interface components:
\begin{description}
  \item [Main Window] The main window. % <-- Not so cool.
  \item [Side Bar] for navigation. % <-- Not so cool.
  \item [Document Tree] A document tree. % <-- Not so cool.
  \item [\hyperlink{gui:mainwindow}{Main Window}] The main window. % <-- way cooler
  \item [\hyperlink{gui:sidebar}{Side Bar}] for navigation. % <-- way cooler
  \item [\hyperlink{gui:documenttree}{Document Tree}] A document tree. % <-- way cooler
\end{description}

\clearpage

\hypertarget{gui:mainwindow}{\subsection{Main Window}}
Some nice long description.

\hypertarget{gui:sidebar}{\subsection{Side Bar}}
Some nice long description.

\hypertarget{gui:documenttree}{\subsection{Document Tree}}
Some nice long description.

\end{document}

Update

Even shorter way, with \deschyperlink as a robust wrapper command:

\documentclass{article}
\usepackage{fontspec} % for xelatex
\usepackage{enumitem}
\usepackage{hyperref}

\setlist[description]{style=nextline,labelwidth=0pt,leftmargin=30pt,itemindent=\dimexpr-20pt-\labelsep\relax} % Global Setup Description List

\DeclareRobustCommand{\deschyperlink}[2]{%
  \hyperlink{#1}{#2}%
}


\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{User Interface}
The following is a list of important user interface components:
\begin{description}
  \item [Main Window] The main window. % <-- Not so cool.
  \item [Side Bar] for navigation. % <-- Not so cool.
  \item [Document Tree] A document tree. % <-- Not so cool.
  \item [\deschyperlink{gui:mainwindow}{Main Window}] The main window. % <-- way cooler
  \item [\deschyperlink{gui:sidebar}{Side Bar}] for navigation. % <-- way cooler
  \item [\deschyperlink{gui:documenttree}{Document Tree}] A document tree. % <-- way cooler
\end{description}

\clearpage

\hypertarget{gui:mainwindow}{\subsection{Main Window}}
Some nice long description.

\hypertarget{gui:sidebar}{\subsection{Side Bar}}
Some nice long description.

\hypertarget{gui:documenttree}{\subsection{Document Tree}}
Some nice long description.

\end{document}
| improve this answer | |
  • Wow thanks for the hasty answer. I don't suppose there is a way to do this without any extra dependencies hmm? (e.g. letltxmacro) (btw I think I have etoolbox as a dependency already). – Jonathan Komar Mar 3 '16 at 14:06
  • 1
    @macmadness86: Well, letltxmacro isn't necessary here, since \item does not really have the optional argument. \let\origitem\item works too. – user31729 Mar 3 '16 at 14:08
  • 1
    Another possibility: Define a robust command, say \myhyperlink which is a wrapper to \hyperlink. This can't break apart then. – user31729 Mar 3 '16 at 14:10
  • 1
    Unrelated: I love the word "robustification" – Jonathan Komar Mar 3 '16 at 14:11
  • @macmadness86: It's an invented word, of course. – user31729 Mar 3 '16 at 14:13

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.