LaTeX forum ⇒ MakeIndex, Nomenclature, Glossaries and AcronymsSuperfluous comma in with \glsaddallunused Topic is solved

Information and discussion about MakeIndex - the tool to generate subject indices for LaTeX documents.
user49915
Posts: 62
Joined: Wed Apr 17, 2019 12:51 pm

Superfluous comma in with \glsaddallunused

Postby user49915 » Tue Nov 05, 2019 7:45 pm

Let us save the source
Code: [Select all] [Expand/Collapse] [Download] ({untitled.tex})
  1. \documentclass{book}
  2. \usepackage[makeindex,nomain]{glossaries-extra}
  3. \setglossarystyle{long3col}
  4. \newcommand{\binding}[2]{#1\nolinebreak{\mapsto}\nolinebreak#2}
  5. \newcommand{\finiteMap}[1]{\mathopen{\glsuseri{not:finiteMap}}#1\mathclose{\glsuserii{not:finiteMap}}}%%% Finite map, e.g., ⦃ x1↦a1, ... xn↦an ⦄.
  6. \newcommand{\infiniteWordsSet}[1]{#1^{\gls{not:infiniteWordsSymbol}}} %%% Infinite sequences
  7. \newglossary[nlg]{notation}{not}{ntn}{List of symbols}
  8. \makeglossaries
  9. \newglossaryentry{not:finiteMap}{type=notation, name={\(\{|\dotso|\}\)}, text={\{|\dotso|\}}, sort={finiteMap}, description={A finite map: \(\{| \binding{c_1}{s_1},\,\dotsc,\,\binding{c_n}{s_n}|\}\) is a function that maps \(c_i\) to \(s_i\) for each \(i\).},user1={\{|},user2={|\}}}
  10. \newglossaryentry{not:infiniteWordsSymbol}{type=notation, name={\(\cdot^{\infty}\)}, text={\infty}, sort={*infiniteWordsSymbol}, description={Given an arbitrary set \(Z\), we denote by \(Z^{\infty}\) the set of all infinite words over \(Z\).}}
  11. \begin{document}
  12. \(\finiteMap{\binding{x}{\infiniteWordsSet{A}}}\)
  13. \backmatter
  14. \glsaddallunused
  15. \printglossaries
  16. \end{document}

in mwe.tex and then run
Code: [Select all] [Expand/Collapse] [Download] ({untitled.tex})
  1. pdflatex mwe && makeindex -s mwe.ist -t mwe.nlg -o mwe.not mwe.ntn

in a loop until the output stabilizes.
Observe the needless comma on the last page of the resulting pdf: "1," in the entry corresponding to finite maps:
mwe.png
mwe.png (215.82 KiB) Viewed 359 times

The entry corresponding to infinite words works as expected, without a comma.

Any help on how to get rid of the superfluous comma? We do need \glsaddallunused, since in a non-minimal example there are some symbols that are explained only in the list of symbols and intentionally not linked (in my non-minimal example, it would be a halmos symbol and "q.e.d.").

The issue has been reported to Nicola with a reference here.

User avatar
nlct
Posts: 276
Joined: Thu Nov 06, 2008 11:15 am

Postby nlct » Thu Nov 07, 2019 3:57 pm

\glsaddallunused is designed to iterate over all defined entries and perform \glsadd[format=glsignore]{label} for every entry that hasn't been marked as used.

The \gls command (and its plural and case-changing variants) is intended as the primary way of referencing entries. This has a notion of "first use", which allows it to vary its behaviour on first use. This is most commonly seen in abbreviations but can also be used with other forms of entries.

Commands like \glsuseri are supplementary commands that may be used to reference specific fields without affecting the "first use" flag, so they don't interfere with the behaviour of \gls.

In your MWE, you have only referenced "not:finiteMap" with these supplementary commands so it hasn't been marked as used. This means that \glsaddallunused does \glsadd[format=glsignore]{not:finiteMap} which creates an invisible location in the location list.

The problem here is that makeindex is specifically an indexing application and it requires a location for each indexed item (unless it's a cross-reference or parent of an indexed item). The same applies to xindy. If you want an entry to appear in the glossary it must be indexed but that means it must also have a location. The \glsignore command simply ignores its argument so can be used to create an invisible location. The idea behind \glsaddallunused is to add an invisible location to any entry that hasn't been marked as used in the hope that will be the only number in the location list. That way the location list will appear empty. Unfortunately if it gets added to an entry that has already been indexed (or is indexed after \glsaddallunused) it results in a spurious comma. In your example, the location list actually has two entries: "1" and "" (empty).

The bib2gls application is specifically designed for glossaries-extra and so allows for entries without locations. The iterative commands \glsaddall and \glsaddallunused don't work with bib2gls. Instead you just use the selection=all option which will include all defined entries regardless of whether or not they have been indexed. It also recognises format=glsignore as indicating an "ignored location" which influences selection but doesn't add the ignored location to the list. Thus avoiding the problem.

If you're not able to use bib2gls then there are several workarounds:
  • If you only have a few entries that aren't indexed in the document but must be included in the glossary then you can explicitly add them with \glsadd[format=glsignore]{label} and remove \glsaddallunused.
  • Explicitly unset the first use flag for any entry that you don't intend to reference with \gls (or its variants). For example, put \glsunset{not:finiteMap} at the start of your definition of \finiteMap.
  • Modify the indexing hook so that it automatically marks the entry as having been used. This option is only available with glossaries-extra.sty not for the base glossaries package and will obviously upset the normal behaviour of \gls.
    Code: [Select all] [Expand/Collapse] [Download] ({untitled.tex})
    1. \renewcommand*{\glsxtrdowrglossaryhook}[1]{\glsunset{#1}}

  • Modify the indexing hook to create a list of all the entries that have been indexed and then iterate over all entries and index all entries that aren't in that list. (Again this option is only available with glossaries-extra.sty). For example, add the following to the preamble:
    Code: [Select all] [Expand/Collapse] [Download] ({untitled.tex})
    1. \newcommand*{\indexedlist}{}
    2. \renewcommand*{\glsxtrdowrglossaryhook}[1]{%
    3. \xifinlist{#1}{\indexedlist}{}{\listxadd{\indexedlist}{#1}}%
    4. }

    and the following at the end of the document:
    Code: [Select all] [Expand/Collapse] [Download] ({untitled.tex})
    1. \forglsentries{\thislabel}{\xifinlist{\thislabel}{\indexedlist}{}{\glsadd[format=glsignore]{\thislabel}}}

Regards
Nicola Talbot


Return to “MakeIndex, Nomenclature, Glossaries and Acronyms”

Who is online

Users browsing this forum: No registered users and 1 guest