# hyperref + glossaries + latex = bad spacing around math relations

Compile the following input with latex && dvips (which you sometimes have to do for a variety of reasons; my case is recompiling old documents):

\documentclass{article}
\usepackage{glossaries}
\newglossaryentry{productOrder}{name={product order}, text={\sqsubseteq}, sort=productOrder, description={foo}}
\begin{document}
\noindent
$$A \sqsubseteq B$$ (good spacing)\\
$$A \gls{productOrder} B$$ (bad spacing)\\
$$A \not\sqsubseteq B$$ (good overlaying)\\
$$A \not\gls{productOrder} B$$ (bad overlaying)
\end{document}


What you get is wrong spacing around the glossary entry and that the slash does not match the symbol:

.

You can also see wrong spacing and overlaying when viewing the dvi file (the links are not hidden there, btw.).

Of course, you can always go with \mathrel{\gls{productOrder}} and \not\mathrel{\gls{productOrder}}. Doing it on each use is, well, tedious, though we could (probably) write a macro for that.

However, compiling the above file with pdflatex produces right spacing and the right overlay, which makes me think that there is a bug inside the hyperref-glossaries package chain. Any bugfix? Exchanging the order of loading the two packages resolves the problem, but the documentation of Nicola advises against it.

• You get the same problem with \hyperlink{glo:productOrder}{\sqsubseteq} which is what \gls{productOrder} is doing, so this seems to be a feature of \hyperlink with latex+dvips rather than a problem with glossaries. (Sorry about the bug tracker not working. The stupid web hosting company decided to remove a load of Perl modules without notice, and without the ability to reinstall them, so all my Perl cgi scripts have stopped working. I'm currently looking for a new web hosting company.) – Nicola Talbot Nov 2 '17 at 18:10
• @NicolaTalbot a suggestion below but it could be a key on \newglossaryentry rather than a hack into \hyperlink (if you are passing by that code again one day:-) – David Carlisle Nov 2 '17 at 21:54
• @DavidCarlisle The next version (1.21) of glossaries-extra will have the ability to switch from the default \hyperlink{target}{\glstextformat{link text}} to \glstextformat{\hyperlink{target}{link text}}. I'll add an answer once I've uploaded it (but there are a few other things that also need sorting out first). – Nicola Talbot Nov 2 '17 at 22:07
• @LeonMeier It's quite possible that Heiko's already noticed this question since it has the hyperref tag, but you could submit a bug report. The simplest MWE that demonstrates the problem is \documentclass{article} \usepackage{hyperref} \begin{document} \hypertarget{target}{Target} $A \sqsubseteq B$ $A \hyperlink{target}{\sqsubseteq} B$ \end{document} It may turn out to be a feature of the dvi engine as hyperref in general works much better with pdflatex. – Nicola Talbot Nov 3 '17 at 10:58

You could do something like the following (with a bit more effort could be integrated as (say) a mathclass=mathrel key in the existing keyval list but here as a command that you can optionally define to force a math class around a defined gls entry.

\documentclass{article}
\usepackage{glossaries}
\makeglossaries

\def\glsmaththing{\csname mathclass\detokenize\expandafter{\glslabel}\endcsname}

\newglossaryentry{productOrder}{name={product order}, text={\sqsubseteq}, sort=productOrder, description={foo}}
\newcommand\mathclassproductOrder{\mathrel}

\begin{document}
\noindent
$$A \sqsubseteq B$$ (good spacing) \\
$$A \gls{productOrder} B$$ (bad spacing)
\end{document}


By default commands like \gls (when used with hyperref) essentially do:

\hyperlink{target}{\glstextformat{text}}


As noted, this works fine for the PDF engine but not with the DVI engine.

The extension package, glossaries-extra, now (as from version 1.21, 2017-11-03) provides a boolean key hyperoutside. The default hyperoutside=true behaves as per the norm for the base glossaries package:

\hyperlink{target}{\glstextformat{text}}


The setting hyperoutside=false, switches the commands around:

\glstextformat{\hyperlink{target}{text}}


Since it's a bit of a nuisance to have to do \gls[hyperoutside=false]{productOrder} all the time, the category attribute hyperoutside can be set instead.

The extension package provides an additional key category that can be used when defining entries. The value is just a label, so you could define your productOrder entry as:

\newglossaryentry{productOrder}{
category=mathrelation,
name={product order},
text={\sqsubseteq}, sort=productOrder, description={foo}}


The mathrelation category can then have the hyperoutside attribute set to false:

\glssetcategoryattribute{mathrelation}{hyperoutside}{false}


This means that \gls{productOrder} will now behave like \gls[hyperoutside=false]{productOrder}, but it won't affect any other entries that you define (unless they also have category=mathrelation).

Now that \glstextformat is outside of \hyperlink it could be redefined to \mathrel:

\renewcommand{\glstextformat}[1]{\mathrel{#1}}


but that will cause a problem for all your other entries.

This new version of glossaries-extra also recognises another attribute textformat which may be set to a control sequence name (without the leading backslash) identifying a command (that takes a single argument) that may be used instead of \glstextformat:

\glssetcategoryattribute{mathrelation}{textformat}{mathrel}


This means that instead of doing

\glstextformat{\hyperlink{target}{text}}


any entry defined with category=mathrelation will do:

\mathrel{\hyperlink{target}{text}}


All other entries will behave as normal.

Here's a complete example including hyperoutside=true for comparison and colorlinks to highlight the hyperlinks:

\documentclass{article}

\usepackage{glossaries-extra}

\glssetcategoryattribute{mathrelation}{hyperoutside}{false}
\glssetcategoryattribute{mathrelation}{textformat}{mathrel}

\newglossaryentry{productOrder}{
category=mathrelation,
name={product order},
text={\sqsubseteq}, sort=productOrder, description={foo}}

\begin{document}
\noindent
$$A \sqsubseteq B$$\\
$$A \gls{productOrder} B$$\\
$$A \gls[hyperoutside]{productOrder} B$$
\end{document}


For the negation, I recommend defining a command that moves the \not inside the link text:

\newcommand*{\notgls}[2][]{\glsdisp[#1]{#2}{\not\glsentrytext{#2}}}


Updated MWE:

\documentclass{article}

\usepackage{glossaries-extra}

\glssetcategoryattribute{mathrelation}{hyperoutside}{false}
\glssetcategoryattribute{mathrelation}{textformat}{mathrel}

\newglossaryentry{productOrder}{
category=mathrelation,
name={product order},
text={\sqsubseteq}, sort=productOrder, description={foo}}

\newcommand*{\notgls}[2][]{\glsdisp[#1]{#2}{\not\glsentrytext{#2}}}

\begin{document}
\noindent
$$A \sqsubseteq B$$\\
$$A \gls{productOrder} B$$\\
$$A \not\gls{productOrder} B$$\\
$$A \notgls{productOrder} B$$
\end{document}


• @LeonMeier I've updated my answer. – Nicola Talbot Nov 4 '17 at 12:49
• @LeonMeier I don't get a correct overlay with pdflatex and \not\gls{productOrder} and glossaries-extra (only with the base glossaries). I think there's too much stuff at the start of \gls (especially with glossaries-extra) for \not to function properly. (There's a lot of initialisation at the start of commands like \gls, processing options, setting defaults etc.) David's answer only works with glossaries not with glossaries-extra. – Nicola Talbot Nov 4 '17 at 14:25
• @LeonMeier No, it just means there's no \printglossary (or \printglossaries) in the example. I omitted it for simplicity since it wasn't relevant. If you add the glossary (\makeglossaries in the preamble and \printglossary in the document) the warning should go away once the associated file has been created by makeindex. – Nicola Talbot Nov 4 '17 at 16:34