1

I am writing on a quite large document and decided to put \LaTeX{} into my glossary

\newglossaryentry{latex}
{
    name={\protect\LaTeX}, 
    description={blabla},
    sort={latex}
}

To link every \LaTeX{} to the glossary, I could replace everytime I used the macro in the text with \gls{latex} but I found it more convenient redefining \LaTeX{}. Unfortunately, it does not work. When I use

\renewcommand{\LaTeX}{\gls{latex}}

Nothing happen. When I use

\DeclareRobustCommand{\LaTeX}{\gls{latex}}

I got !TeX capacity exceeded, sorry [grouping levels=255] So I thought, I may need to avoid \LaTeX inside the glossary itself and added

\DeclareRobustCommand{\origLaTeX}{\LaTeX}
\newglossaryentry{latex}
{
    name={\protect\origLaTeX}, 
    description={blabla},
    sort={latex}
}

But I still got the error:

! TeX capacity exceeded, sorry [grouping levels=255].
\XC@edef #1#2->\begingroup
\ifnum \catcode `\!=13 \edef !{\string !}\fi \ifn...
l.1 ...some text with \LaTeX macro in it
7
  • Not that it is important, but for me \renewcommand{\LaTeX}{\gls{latex}} also errors in a small example (gist.github.com/moewew/30646181ab021d6c4fdbe00e0a6d4d2c). The problem here and with \DeclareRobustCommand{\LaTeX}{\gls{latex}} is that you essentially end up defining \LaTeX as calling \LaTeX again (\gls{latex} ends up calling \protect\LaTeX) and so you get this infinite loop. With \DeclareRobustCommand{\origLaTeX}{\LaTeX} you cannot avoid the loop, since now \gls{latex} calls \protect\origLaTeX, which is \LaTeX, so you again have \LaTeX calling itself. – moewe Mar 29 at 15:42
  • 1
    You could use the new \NewCommandCopy to really copy the definition of \LaTeX to \origLaTeX: gist.github.com/moewew/b02f533a51131ee10beba9de3aaaefcf. But I don't think this is a particularly good idea. I'd probably just stick with using \gls{latex} or at least use a macro name for it that isn't already taken. – moewe Mar 29 at 15:45
  • @moewe Of course, I understand that. However, from a discussion like this tex.stackexchange.com/questions/51401/…, I got the impression that defining an intermediate macro like \origLaTeX would fix the issue. But it doesnt. I also tried the version \let\origLaTeX\LaTeX as suggested in that question but it didn't help either. – Highchiller Mar 30 at 7:02
  • @moewe Can you elaborate a little why using \NewCommandCopy is not a "particularly good idea"? – Highchiller Mar 30 at 7:13
  • Yes, an intermediate macro does help, but it depends how it is defined. With \newcommand*{\origLaTeX}{\LaTeX} you just have \origLaTeX expand to \LaTeX, which still gives you infinite recursion. But with \let\x\y the definition of \y is copied into \x, so \x does not expand to \y it expands to \y's definition/expansion. The problem here is that \LaTeX is a robust macro, which is defined internally via a helper macro, and so it cannot be \let around 'just like that'. That's what \NewCommandCopy takes care of. ... – moewe Mar 30 at 7:40
3

When we define

\renewcommand{\LaTeX}{\gls{latex}}

we tell TeX that the macro \LaTeX should expand to \gls{latex}. So whenever TeX encounters \LaTeX, it will just try to use \gls{latex} instead.

Thanks to

\newglossaryentry{latex}
{
    name={\protect\LaTeX}, 
    description={blabla},
    sort={latex}
}

\gls{latex} will end up printing \protect\LaTeX in many cases (amongst other things; the command does more). But now LaTeX sees the \LaTeX in \protect\LaTeX, expands it and sees that it expands to \gls{latex}. This results in the infinite loop you get.

The result is pretty much the same with

\DeclareRobustCommand{\LaTeX}{\gls{latex}}

Here LaTeX doesn't define \LaTeX to be \gls{latex} directly. Instead it defines \LaTeX via an auxiliary macro that then expands to \gls{latex}. This just adds one further layer to our infinite loop, but does not change the end result.


We could avoid the issue if could copy the actual definition of \LaTeX and give it a different name. Then we could overwrite \LaTeX and define it in terms of our copy of \LaTeX. That way we get out of the infinite loop because no macro tries to expand itself.

That is the approach with \let\origLaTeX\LaTeX. Unfortunately, this does not work since \LaTeX is defined with \DeclareRobustCommand{\LaTeX}, which – as alluded to above – does not actually define \LaTeX directly, it defines it via a helper macro, which contains the actual definition. When we do \let\origLaTeX\LaTeX, TeX copies the definition of \LaTeX into \origLaTeX. But the helper macro that actually contains the definition of \LaTeX is not copied over or changed. Since we defined our new version of \LaTeX also with \DeclareRobustCommand{\LaTeX}{\gls{latex}}, \origLaTeX actually ends up calling \gls{latex} via the helper again.

Long story short, you cannot properly use \let with macros defined via \DeclareRobustCommandSometimes people get lucky and things appear to work, but this is not something you can rely on.. That's why the package letltxmacro was written. See also https://tex.stackexchange.com/a/47372/35864. With a current version of LaTeX, you won't need an extra package, you can use \NewCommandCopy to actually copy macro definitions without having to worry if the macro was defined with \newcommand or \DeclareRobustCommand.

Hence

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{csquotes}
\usepackage{glossaries}

\newglossaryentry{latex}
{
  name={\protect\origLaTeX}, 
  description={blabla},
  sort={latex}
}

\makeglossaries

\NewCommandCopy\origLaTeX\LaTeX
\renewcommand*{\LaTeX}{\gls{latex}}

\begin{document}
\LaTeX

\printglossaries
\end{document}

works as desired and produces

LaTeX logo in text and "LaTeX blabla. 1" in glossary.


As I said in the comments I don't think there is a TeXnical reason why using \NewCommandCopy is not a particularly good idea here: It's just we'd change the definition of a LaTeX core macro to do something very different from its original definition. That can have unintended consequences when code you don't have control over uses that macro. Granted, for \LaTeX that probably is not much of a concern. But in general redefining core macros in a way that makes them do a whole lot more than before can be dangerous.

2
  • Beautiful, thank you! One minor comment. After \begin{document} should be \LaTeX rather than \gls{latex} because that was the whole point of it :) – Highchiller Apr 1 at 6:23
  • @Highchiller Oops. Thanks for catching that. Fixed. – moewe Apr 1 at 6:31

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.