3

I'm working on my thesis and was initially using the basic glossaries package, and recently switched over to glossaries-extras for its more robust handling of multiple glossaries. I have a list of acronyms separate from my main glossary, and many of those acronyms have corresponding definitions in the glossary. The glossaries user manual provides the dual entry example for this exact situation:

\newcommand*{\newdualentry}[5][]{%
  % main entry:
  \newglossaryentry{main-#2}{name={#4},%
  text={#3\glsadd{#2}},%
  description={#5},%
  #1% additional options for main entry
  }%
  % abbreviation:
  \newacronym{#2}{#3\glsadd{main-#2}}{#4}%
}

along with the observation:

For this trivial document, this kind of dual entry is redundant and unnecessarily leads the reader down a trail, first to the list of acronyms and from there the reader then has to go to the main glossary to look up the description.

I'm trying to circumvent this problem by linking directly to the main glossary entry for dual entries instead of linking to the acronym. For instance, in this document:

Screenshot of desired typesetting result in the document body

I want the links for simultaneous localization and mapping (SLAM) using \gls{slam} to target the corresponding glossary entry. The ordinary glossary and acronym linking behavior is fine as-is.

How can I change the hyperlink target for dual entries?

So the autonomous mobile robot (AMR) reference \gls{amr} should continue to target the list of acronyms:

Screenshot of typeset list of acronyms

while \gls{slam}and \gls{end-effector} should target the main glossary:

Screenshot of typeset glossary

The following MWE was used to create the above screenshots. The newdualentry example has been tweaked for my needs:

\documentclass{report}

\usepackage[colorlinks]{hyperref}
\usepackage[acronym]{glossaries-extra}

\setabbreviationstyle[acronym]{long-short}

\newcommand*{\newdualentry}[5][]{%
  \newglossaryentry{main.#2}{%
    name={#4 (\glslink{#2}{#3})},%
    text={#3},%
    description={#5},%
    #1%
  }%
  \newacronym{#2}{#3}{#4}%
}

\makeglossaries

\newacronym{amr}{AMR}{autonomous mobile robot}

\newdualentry{slam}{SLAM}{simultaneous localization and mapping}{
  Update a map of an uncertain environment (mapping) while simultaneously
  maintaining an estimate of location within that environment (localization).
}

\newglossaryentry{end-effector}{
  name={end-effector},
  description={
    Device specifically designed for attachment to the mechanical-interface to
    enable the robot to perform its task.
  }
}

\setlength{\parindent}{0pt}

\begin{document}
\section{Current Effect}

Both of these link to the acronym listing, which I *do not* want: \\
  \hspace*{1cm} First use: \gls{slam}. \\
  \hspace*{1cm} Next use: \gls{slam}.

Acronym-only entires link to the acronym listing, which *is* what I want: \\
  \hspace*{1cm} First use: \gls{amr} \\
  \hspace*{1cm} Next use: \gls{amr}.

Glossary-only entries link to the glossary entry, which as also good: \\
  \hspace*{1cm} \gls{end-effector}


\section{Desired Effect}

I want the \texttt{\textbackslash gls\{slam\}} macro from above to behave as if
I had done: \\
  \hspace*{1cm} First use: \glslink{main.slam}{\glsxtrfull{slam}}. \\
  \hspace*{1cm} Next use: \gls{main.slam}. \\
where these two link to the full glossary entry, similar to \gls{end-effector}.

\printacronyms[title={List of Acronyms}]
\printglossary

\end{document}

Clarifications

A comment by @cfr suggested using a prefix on the acronym label instead of the main entry:

\newcommand*{\newdualentry}[5][]{%
  \newglossaryentry{#2}{%
    name={#4 (\glslink{acr-#2}{#3})},%
    text={#3},%
    description={#5},%
    #1%
  }%
  \newacronym{acr-#2}{#3}{#4}%
}

but this forfeits the automatic expansion to the full long-short text on first use. Compare SLAM and AMR when using this approach:

Screenshot showing user cfr's suggestion in use

This is addressed in her full answer.

2
  • \newcommand*{\newdualentry}[5][]{% \newglossaryentry{#2}{% name={#4 (\glslink{acr-#2}{#3})},% text={#3},% description={#5},% #1% }% \newacronym{acr-#2}{#3}{#4}% }?
    – cfr
    Commented Mar 30 at 4:16
  • @cfr Edited the question in response to this.
    – drmuelr
    Commented Mar 30 at 4:42

2 Answers 2

3

You can simply modify the macro you're using to define dual entries so that it does what you want. \gls{<label>} wants to link to the entry with label <label>, so let it. Drop the main. prefix and instead prefix the acronym in these cases. That doesn't matter to what you do in the document because the only things linking to the acronyms in the case of dual entries are the glossary entries and we can just add the prefix in the definition of our macro accordingly.

To get the precise output you show, you also need to add a key to make sure you get the right output on first use. But again, that can be done by just modifying your dual-setup macro.

\newcommand*{\newdualentry}[5][]{%

Drop the main. prefix. We want #2 to link to the glossary entry so that's what we should use here.

  \newglossaryentry{#2}{%

Obviously, we need a different label for the acronym now, so we have to make our link target the correct place (or we'd have a self-referring entry).

    name={#4 (\glslink{acr-#2}{#3})},

We also want to get the correct output on first use, which isn't, by default, the same as for an acronym. To avoid the use of text on first use, we need to specify first (since text overrides name on first use).

    first={#4 (\gls{acr-#2})},
    text={#3},
    description={#5},
    #1,
  }%

Finally, we need to make sure the acronym uses the correct label.

  \newacronym{acr-#2}{#3}{#4}%
}

Job done.

Complete code

I only modified the document source for the last part where you deliberately used input you don't want to produce the output you do. Since the input you do want now produces that output, I adjusted accordingly.

\documentclass{report}

\usepackage[colorlinks]{hyperref}
\usepackage[acronym]{glossaries-extra}

\setabbreviationstyle[acronym]{long-short}

\newcommand*{\newdualentry}[5][]{%
  \newglossaryentry{#2}{%
    name={#4 (\glslink{acr-#2}{#3})},
    first={#4 (\gls{acr-#2})},
    text={#3},
    description={#5},
    #1,
  }%
  \newacronym{acr-#2}{#3}{#4}%
}

\makeglossaries

\newacronym{amr}{AMR}{autonomous mobile robot}

\newdualentry{slam}{SLAM}{simultaneous localization and mapping}{
  Update a map of an uncertain environment (mapping) while simultaneously
  maintaining an estimate of location within that environment (localization).
}

\newglossaryentry{end-effector}{
  name={end-effector},
  description={
    Device specifically designed for attachment to the mechanical-interface to
    enable the robot to perform its task.
  }
}

\setlength{\parindent}{0pt}

\begin{document}
\section{Current Effect}

Both of these link to the acronym listing, which I *do not* want: 

  \hspace*{1cm} First use: \gls{slam}. 

  \hspace*{1cm} Next use: \gls{slam}.

Acronym-only entires link to the acronym listing, which *is* what I want: 

  \hspace*{1cm} First use: \gls{amr} 
  
  \hspace*{1cm} Next use: \gls{amr}.

Glossary-only entries link to the glossary entry, which as also good: 

  \hspace*{1cm} \gls{end-effector}


\section{Desired Effect}

I want the \texttt{\textbackslash gls\{slam\}} macro from above to behave as if
I had done: 

First use:  \glsreset{slam}\gls{slam}.

Next use: \gls{slam}. 

where these two link to the full glossary entry, similar to \gls{end-effector}.

\printacronyms[title={List of Acronyms}]
\printglossary

\end{document}

[Please note I can't currently add an image due to an Okular bug. I'm not sure that matters here as an image won't show the linking anyway.]

2
  • Is there any reason to use acr- vs acr. as a prefix? I haven't been able to pick out a pattern in the glossary manuals of dots vs dashes.
    – drmuelr
    Commented Mar 30 at 5:05
  • 1
    @drmuelr None. I just know hyphens work because that's my go-to delimiter for glossaries so I feel confident using it in an answer that I'm not likely to be unleashing any nasty surprises on anybody who uses my code. If you prefer dots and they work, stick to them. I also find dots less clear because they're easier to confuse with commas on a small screen. That makes debugging harder. But really, it's just habit. In fact, I almost used a dot because you had. But then I'd have felt an obligation to check the documentation to make sure it was safe.
    – cfr
    Commented Mar 30 at 5:47
1

cfr's answer is great as a simple solution, but it was causing problems with \glsxtrfull and related macros throughout my project where I need to override first-use behaviors -- and there are a lot of them.

After looking through glossaries-extra.sty v1.53: documented code, I came up with another solution, again centered on the \newdualentry macro. The big idea is to set the alias key of the acronym entry:

This is similar to the see key but the value can only be a single entry label. In addition to automatically indexing the cross-reference, this command will cause the entry with this key to have hyperlinks go to the aliased entry when referenced with commands like \gls. Whenever the entry is indexed with commands like \gls, the indexing will be performed on the target entry (the alias value). See §5.9 for further details.

Any entry that has a see, seealso or alias key set will be added to the glossary by default when using makeindex or xindy. If you don’t want this behaviour, use the autoseeindex=false package option and implement a post-description hook to insert the cross-reference.

which makes this a seamless solution for my project, but with the drawback that linking to entries in the list of acronyms gets nasty. This isn't a problem for me since I don't plan to ever do so beyond the dual glossary entries. The complete macro is:

\newcommand*{\newdualentry}[5][]{%
  \newglossaryentry{main.#2}{%
    name={#4 (\glsxtrhyperlink{glo:#2}{{\glsxtrprotectlinks#3}})%
      \glsadd{#2}%
    },%
    text={#3},%
    description={#5},%
    #1%
  }%
  \newacronym{#2}{#3}{#4}%
  \GlsXtrSetField{#2}{alias}{main.#2}%
}

Breaking this down...

\newcommand*{\newdualentry}[5][]{%
  \newglossaryentry{main.#2}{%

I keep the main. prefix.

    name={#4 (\glsxtrhyperlink{glo:#2}{{\glsxtrprotectlinks#3}})%
      \glsadd{#2}%
    },%

the name field gets replaced by this monstrosity. \glslink{#2}{#3} won't work here because glossaries will replace #2 with the aliased label, main.#2, meaning the main entry would just link to itself.

Instead, I use \glsxtrhyperlink{<target>}{<text>}, where the glo: prefix in the target is used behind the scenes by glossaries. This is based on \glsxtrdohyperlink in §1.3.4 of the documented code, where the alias hyperlink replacement is done. I spent a few hours trying to find a way to use some other glossaries mechanism, but this is the best I could come up with.

Since I'm not using \glslink, I use \glsadd{#2} to add this location to the acronym index. This replaces the post-description hook mentioned above when using the autoseeindex=false package option.

    text={#3},%
    description={#5},%
    #1%
  }%
  \newacronym{#2}{#3}{#4}%
  \GlsXtrSetField{#2}{alias}{main.#2}%
}

acronyms don't define the alias key, but the underlying field still works as described above. Thus, \GlsXtrSetField lets me define the field after creating the acronym.

The rest of the code works without modification, and does exactly what I wanted.

You must log in to answer this question.

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