# Generate macros for glossary terms to improve source readability

With glossaries-extra, I would like to generate macros for each glossary term to improve readability of the latex sources. I find it difficult to read text that looks like this (especially if it is a longer text):

\Glspl{pig} or \gls{pig}? \Gls{cat} or \glspl{cat}?


What's distracting me is that capitalization and number are in the command, not in the term. Ideally, the line would read,

\Pigs or \pig? \Cat or \cats?


However, that does not work because it causes trouble with the next whitespace. To deal with that problem my preferred choice is \Pigs/.

Generating macros of that form is possible using \edef in the <code> part of \glsforeachincategory{<category-list>}{<category>}{<label>}{<code>}. Making macros for plural and singular is easily achieved by appending an s to the label.

Two problems remain:

• Depending on the terms, there may be clashes with existing command names. The solution should have minimal impact both visually and in terms of character count. My current solution is to prepend x to the label, yielding \xPigs/, but I am not happy because there may still be clashes and readability could be better. Prepending _ (\_Pigs/) or . (\.Pigs/), which would be better readable, do not work. Any suggestions?

• The capitalization of the term is what I cannot get to work at all. My current solution is to capitalize the prepended x, i.e. \Xpigs/. So the question is: How to generate a macro named \xPigs/ through \defGlspl#1 (see below) when the argument expands to pig?

More general remarks or alternative approaches are welcome, too!

\documentclass{article}
\usepackage[automake]{glossaries-extra}

% two glossary entries, pig and cat, for our example.
\newglossaryentry{pig}
{
name={pig},
description={A pig is any of the animals in the genus Sus.},
category={animals}
}

\newglossaryentry{cat}
{
name= {cat},
description= {The cat (Felis catus) is a small carnivorous mammal.},
category={animals},
}

\makeglossaries

% macros defining macros that
% * expand to a glossary command (e.g. \gls)
% * do not inhibit readability (regarding capitalization and singular/plural))
\def\defgls#1{\expandafter\edef\csname x#1\endcsname/{\gls{#1}}}
\def\defGls#1{\expandafter\edef\csname X#1\endcsname/{\Gls{#1}}}
\def\defglspl#1{\expandafter\edef\csname x#1s\endcsname/{\glspl{#1}}}
\def\defGlspl#1{\expandafter\edef\csname X#1s\endcsname/{\Glspl{#1}}}

% apply the macros for all glossary terms in a category
\glsforeachincategory{animals}{\cat}{\lab}{%
\defgls\lab%
\defGls\lab%
\defglspl\lab%
\defGlspl\lab%
}

%%% My question %%%
% how to change \defGls#1 and \defGlspl#1 above
% to generate the macros below that, for the demo,
% I wrote by hand (for the pig and cat entry)
% (the difference is the capitalization of the macro name)
\def\xPigs/{\Glspl{pig}}
\def\xPig/{\Gls{pig}}
\def\xCats/{\Glspl{cat}}
\def\xCat/{\Gls{cat}}

\begin{document}

% demo

% I find this hard to read and scan for errors
\Glspl{pig} or \gls{pig}? \Gls{cat} or \glspl{cat}?

% Better:
\Xpigs/ or \xpig/? \Xcat/ or \xcats/?

% what I would like:
%% note the difference
%% above:\Xpigs/ below: \xPigs/
%% above:\Xcat/, below:\xCat/)
\xPigs/ or \xpig/? \xCat/ or \xcats/?

\def\Pigs/{Pigs}
\def\pig/{pig}
\def\Cat/{Cat}
\def\cats/{cats}
%ideal, but unrealistic because of possible name-clashes:
\Pigs/ or \pig/? \Cat/ or \cats/?

\printglossaries

\end{document}

• You are aware that there are existing macros starting with x too? Also what will you do with glossary terms like H2O or km/h? What about math? Won't the use of / as command terminator be confusing there? – Ulrike Fischer Jun 14 at 12:35
• Thanks for the reminder to be cautious! I don't like the \xPigs/ solution so much because a) it may lead to clashes, as you point out, and b) it isn't great for readability. However, it still works because in case of a clash you can change the label of your term. Also, you can choose which category of terms to apply it to, so if you have a category with a lot of clashes, use the normal approach. In many cases, the normal approach is ok in terms of readability. H2O and km/h are such cases, and I would probably not apply the approach to them. – fkleedorfer Jun 14 at 12:59
• One could probably use xstring to create a context dependent version based on whether the first character was \uppercase and whether it ended with s, but this would fail on words like geese or radius. – John Kormylo Jun 14 at 15:11
• I would not mind wrong plurals loke gooses or radius.. maybe one could handle that using the plural field of the entry, but that is another problem. I would be grateful for a running demo of your idea! I have been working with Uppercase, MakeUppercase, and mfirstuc to no avaial so far. – fkleedorfer Jun 15 at 6:40
• @Ulrike I found part of the answer to my problem in another answer you wrote: tex.stackexchange.com/a/387819/191028 - I tried to use \uppercase with \csname...\endcsname not knowing that it isnt expandable. \csname requires that its argument be only characters after expansion. – fkleedorfer Jun 15 at 11:52

The main problem is solved, using the trick in egreg's answer to this Question.

The trick is applied in the macros \myUpper and myUpperAux in the code below - see comments there for detailed explanation.

With this code, it's possible to write \xGlossaryTerms/ where normally one would have to use \Glspl{glossaryTerm}.

\documentclass{article}
\usepackage[automake]{glossaries-extra}

% two glossary entries, pig and cat, for our example.
\newglossaryentry{pig}
{
name={pig},
description={A pig is any of the animals in the genus Sus.},
category={animals}
}

\newglossaryentry{cat}
{
name= {cat},
description= {The cat (Felis catus) is a small carnivorous mammal.},
category={animals},
}

\makeglossaries

% solution based on the accepted answer of
% https://tex.stackexchange.com/questions/57551/create-a-capitalized-macro-token-using-csname
\def\myUpperAux#1#2#3\relax{%
% the \def here is required because \uppercase will replace tokens with
% their uppercase form, but will not touch control sequences.
% With the trick from the stackexchange answer:
% #1 is the first token of the input
% #2 is the second token of the input
% #3 is the rest of the input
% we define a temporary macro for the value of #1 so it doesn't get uppercased
% we uppercase the edef with csname
\def\tmpMyUpperAux{#1}%
\uppercase{\expandafter\edef\csname \tmpMyUpperAux#2}#3\endcsname/%
}
\newcommand\myUpperDef[1]{%
% \edef here forces expansion of #1. We need it as a sequence of tokens instead of
% whatever control sequences it actually is because the the macro \myUpperAux
% wants to split off the first two tokens and uppercase the second
\edef\myUpperDefTmp{#1}%
\expandafter\myUpperAux\myUpperDefTmp\relax%
}

% macros defining macros that
% * expand to a glossary command (e.g. \gls)
% * do not inhibit readability (regarding capitalization and singular/plural))
\def\defgls#1{\expandafter\edef\csname x#1\endcsname/{\gls{#1}}}
\def\defGls#1{\myUpperDef{x#1}{\Gls{#1}}}
\def\defglspl#1{\expandafter\edef\csname x#1s\endcsname/{\glspl{#1}}}
\def\defGlspl#1{\myUpperDef{x#1s}{\Glspl{#1}}}

% apply the macros for all glossary terms in a category
\glsforeachincategory{animals}{\cat}{\lab}{%
\defgls{\lab}%
\defGls{\lab}%
\defglspl{\lab}%
\defGlspl{\lab}%
}

\begin{document}

% demo

% I find this hard to read and scan for errors
\Glspl{pig} or \gls{pig}? \Gls{cat} or \glspl{cat}?

% here is the desired (but not ideal) solution:
\xPigs/ or \xpig/? \xCat/ or \xcats/?

\def\Pigs/{Pigs}
\def\pig/{pig}
\def\Cat/{Cat}
\def\cats/{cats}
% ideal, but unrealistic because of possible name-clashes:
\Pigs/ or \pig/? \Cat/ or \cats/?
% ... still interested in a better way to avoid name clashes with minimal
% impact on source readability at the same time.

\printglossaries

\end{document}