4

I'm working on a document that contains a set of sections describing some technical objects. The object names contain underscores (very common in that programming environment), so I've loaded the package underscore.

Now I want to link from other parts of the document to the reference section. Underscores in labels (e. g. \label{sec:ref-struct-FOO_BAR}) seem to cause all kinds of trouble, so I've simply replaced the underscores with dashes in the labels: \label{sec:ref-struct-FOO-BAR}. This works so far.

As a next step, I would like to provide a custom macro that is called with the object name (containing an underscore) and then both typesets that name (with an underscore) and places a link (where all underscores are replaced by dashes). An example:

\documentclass{article}
\usepackage{fancyref}
\usepackage{hyperref}
\usepackage{underscore} 

\newcommand{\componentname}[1]{\texttt{#1}}
\newcommand{\structurename}[1]{\texttt{#1}}

\newcommand{\componentref}[2]{\hyperref[sec:ref-comp-#1]{\componentname{#2}}}
\newcommand{\structureref}[2]{\hyperref[sec:ref-struct-#1]{\structurename{#2}}}

\begin{document}

\tableofcontents

\clearpage

\section{Text}

% Where I came from:
We use component \componentname{AB_CD} (see \fref{sec:ref-comp-AB-CD}) to generate 
structure \structurename{FOO_BAR} (see \fref{sec:ref-struct-FOO-BAR}).

% How far I got:
We use component \componentref{AB-CD}{AB_CD} to generate structure \structureref{FOO-BAR}{FOO_BAR}.

% What I really want:
% We use component \componentref{AB_CD} to generate structure \structureref{FOO_BAR}.

\section{Reference}

\subsection{Structures}

\subsubsection{Structure \structurename{FOO_BAR}}
\label{sec:ref-struct-FOO-BAR}

Text

\subsubsection{Structure \structurename{BOO_FAR}}
\label{sec:ref-struct-BOO-FAR}

Text

\subsection{Components}


\subsubsection{Component \componentname{AB_CD}}
\label{sec:ref-comp-AB-CD}

Text

\subsubsection{Component \componentname{EFG_HIJ}}
\label{sec:ref-comp-EFG-HIJ}

Text

\end{document}

I'd like to use something like

\usepackage{xstring}
% ...
\newcommand{\fancycomponentref}[1]{\hyperref[sec:ref-comp-\StrSubstitute{#1}{_}{-}]{\componentname{#1}}}

but that doesn't work, and I haven't found a viable solution yet. What options do I have to implement this?

4

You don't need the underscore package:

\documentclass{article}
\usepackage{fancyref}
\usepackage{hyperref}

\newcommand{\componentname}[1]{\texttt{#1}}
\newcommand{\structurename}[1]{\texttt{#1}}

\newcommand{\componentref}[1]{\hyperref[sec:ref-comp-#1]{\componentname{#1}}}
\newcommand{\structureref}[1]{\hyperref[sec:ref-struct-#1]{\structurename{#1}}}

\begingroup\lccode`~=`_ \lowercase{\endgroup\let~}_
\catcode`_=12

\begin{document}

\tableofcontents

\clearpage

\section{Text}

% Where I came from:
We use component \componentname{AB_CD} (see \fref{sec:ref-comp-AB_CD}) to generate 
structure \structurename{FOO_BAR} (see \fref{sec:ref-struct-FOO_BAR}).

% How far I got:
We use component \componentref{AB_CD} to generate structure \structureref{FOO_BAR}.

\section{Reference}

\subsection{Structures}

\subsubsection{Structure \structurename{FOO_BAR}}
\label{sec:ref-struct-FOO_BAR}

Text and math $a_1$

\subsubsection{Structure \structurename{BOO_FAR}}
\label{sec:ref-struct-BOO_FAR}

Text

\subsection{Components}


\subsubsection{Component \componentname{AB_CD}}
\label{sec:ref-comp-AB_CD}

Text

\subsubsection{Component \componentname{EFG_HIJ}}
\label{sec:ref-comp-EFG_HIJ}

Text

\end{document}

enter image description here

  • The "real" application is a 480+-page document with a lot of stuff in it. I've tried to replace the underscore package with your catcode enchantments, but I get "missing $ inserted" errors all over the place. I don't even know where I should start to find out where that comes from... :-( – vwegert Feb 4 '15 at 9:40
  • @vwegert Sorry, but without a minimal example it's impossible to say more. – egreg Feb 4 '15 at 9:42
  • I understand that. While I got the message that in this particular minimal example, I don't need the underscore package, is there a way to get this working without removing the package? – vwegert Feb 4 '15 at 9:48
  • @vwegert underscore makes the underscore active, with a non expandable definition, so _ can't be used in labels. – egreg Feb 4 '15 at 9:51
  • 1
    @Alberto for such an application I’d do differently. Look for \detokenize – egreg Jun 3 at 15:16

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.