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 –  Mar 03 '16 at 13:59
  • I wrapped the \hyperlinks in curly braces and it worked... (XeTeX 2.6) – Tom Jun 29 '18 at 13:56

2 Answers2

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}
  • 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 03 '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. –  Mar 03 '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. –  Mar 03 '16 at 14:10
  • 1
    Unrelated: I love the word "robustification" – Jonathan Komar Mar 03 '16 at 14:11
  • @macmadness86: It's an invented word, of course. –  Mar 03 '16 at 14:13
  • @macmadness86: I've added the 'shortest' possible solution, I think ;-) –  Mar 03 '16 at 14:20
0

Simply wrapping the \hyperref in curly braces should do the trick.

@Tom wrote this in a comment, but I (not a TeXpert) think this is a legitimate answer, because it works just as expected. This answer ist just for visibility.