[Tex/LaTex] glossaries special sorting for one glossary

glossariesxindy

In my document I use several glossaries, one of which is for the nomenclature. I have some special wishes for the sorting of this glossary. The easist way to achieve what I want is if I could give the sort=def option for only one glossary, but as fasr as I can tell this is only available as a package option.

Therefore I think I might have to write my own rules. Since I have no experience with xindy what soever I would like to know if the following rules are a good starting point.

What I want:

  1. a term X prefixed with # comes right after X
  2. if a term X is followed by an underline it comes right after X and before #X

Example

 X
#X
 X_index
#X_index
 Xindex
#Xindex

What I think might be reasonable rules after looking here:

(merge-rule "<startOfLine>\#"(.*)<endOfLine>" "\1~e")
(merge-rule "<startOfLine>(.*[^~e])<endOfLine>" "\1~b")
(merge-rule "_" "~b")

I am not sure how to force a match for the entire line with the first rule.
I am not sure either how to formulate the does not end with last character bit in the second rule. The second rule aims to prevent \#X ending up behind Xa.

Furthermore I looked at samplexdy.tex from the glosaries package (docfolder/samples) and noted that the according xindy file looked huge, so any pointers on where I insert my rules or what I actually need would be apreciated. And how do I teach glossaries that I want to use the modified xindy file only for one glossary out of several?

Best Answer

As from glossaries version 4.04, it's now possible to use different sort methods, but only if you use the \makenoidxglossaries option which uses TeX to perform the sorting:

\documentclass{article}

\usepackage[nopostdot,nogroupskip]{glossaries}

\newglossary{nomen}{}{}{Nomenclature}

\makenoidxglossaries

% main glossary

\newglossaryentry{goose}{name={goose},description={}}
\newglossaryentry{zebra}{name={zebra},description={}}
\newglossaryentry{duck}{name={duck},description={}}
\newglossaryentry{aardvark}{name={aardvark},description={}}

% nomenclature
\newglossaryentry{X}{type=nomen,name={X},description={}}
\newglossaryentry{hashX}{type=nomen,name={\#X},description={}}
\newglossaryentry{X-index}{type=nomen,name={X\_index},description={}}
\newglossaryentry{hashX-index}{type=nomen,name={\#X\_index},description={}}
\newglossaryentry{Xindex}{type=nomen,name={Xindex},description={}}
\newglossaryentry{hashXindex}{type=nomen,name={\#Xindex},description={}}

\begin{document}
Test document.

\glsaddall

\printnoidxglossary[sort=word]

\printnoidxglossary[type=nomen,sort=def]

\end{document}

(Two LaTeX runs are required to display the glossaries.) This produces:

Image of resulting glossaries

The drawback here is that when this method is used for alphabetical sorting it can be very slow, orders by character code, and has problems if the sort value contains commands. The glossaries-extra extension package provides a hybrid method allowing you to use makeindex/xindy for the alphabetical sorting and the "noidx" method for ordering by use/definition.

\documentclass{article}

\usepackage[nogroupskip]{glossaries-extra}

\newglossary{nomen}{}{}{Nomenclature}

\makeglossaries[main]

% main glossary

\newglossaryentry{goose}{name={goose},description={}}
\newglossaryentry{zebra}{name={zebra},description={}}
\newglossaryentry{duck}{name={duck},description={}}
\newglossaryentry{aardvark}{name={aardvark},description={}}

% nomenclature
\newglossaryentry{X}{type=nomen,name={X},description={}}
\newglossaryentry{hashX}{type=nomen,name={\#X},description={}}
\newglossaryentry{X-index}{type=nomen,name={X\_index},description={}}
\newglossaryentry{hashX-index}{type=nomen,name={\#X\_index},description={}}
\newglossaryentry{Xindex}{type=nomen,name={Xindex},description={}}
\newglossaryentry{hashXindex}{type=nomen,name={\#Xindex},description={}}

\begin{document}
Test document.

\glsaddall

\printglossary

\printnoidxglossary[type=nomen,sort=def]

\end{document}

The optional argument to \makeglossaries should be a list of glossary labels identifying those that need sorting by makeindex (or xindy if the xindy package option is used). Any remaining glossaries (nomen in this case) are treated as though \makenoidxglossaries was used. The result is the same as the previous example but the build process needs to include makeindex/xindy (either explicitly or through the helper scripts makeglossaries or makeglossaries-lite). Both makeglossaries and makeglossaries-lite can detect from the .aux file that only the main glossary needs processing for this example.

There is also a third method which is to use glossaries-extra with bib2gls. This requires some modification to the document as now the entries must be defined in one or more .bib files.

For example, the file entries.bib may contain the alphabetical entries. If the entry has a description you can use @entry:

@entry{goose,
  name={goose},
  plural={geese},
  description={long-necked waterbird}
}

If the entry doesn't have a description you can use @index:

@index{goose,
  name={goose},
  plural={geese}
}

With @index if the name field exactly matches the label, you can omit it:

@index{goose,
  plural={geese}
}

(You can't do this with @entry.) The label may only contain UTF-8 characters if you are using XeLaTeX or LuaLaTeX.

So here's entries.bib:

@index{goose,
 plural={geese}
}

@index{zebra}

@index{duck}

@index{aardvark}

The other entries can be defined with @entry. For example:

@entry{X,
  name={X},
  description={}
}

but since these entries are like symbols, you can use @symbol instead (which, like @index, doesn't require the description field):

@symbol{X,
  name={X}
}

Here's symbols.bib:

@symbol{X,
  name={X}
}

@symbol{hashX,
  name={\#X}
}

@symbol{X-index,
  name={X\_index}
}

@symbol{hashX-index,
  name={\#X\_index}
}

@symbol{Xindex,
  name={Xindex}
}

@symbol{hashXindex,
  name={\#Xindex}
}

The document now looks like:

\documentclass{article}

\usepackage[record,% use bib2gls
 nogroupskip]{glossaries-extra}

\newglossary{nomen}{}{}{Nomenclature}

\GlsXtrLoadResources[
  src={entries}, % terms defined in entries.bib
  type={main}, % put these terms in the 'main' glossary
  save-locations=false,% no location list required
  selection={all}% select all terms
]

\GlsXtrLoadResources[
  src={symbols}, % terms defined in symbols.bib
  type={nomen}, % put these terms in the 'nomen' glossary
  sort=none,% don't sort
  save-locations=false,% no location list required
  selection={all}% select all terms
]


\begin{document}
Test document.

\printunsrtglossaries

\end{document}

If the file is called myDoc.tex then the document build is:

pdflatex myDoc
bib2gls myDoc
pdflatex myDoc

(If you want letter groups you need bib2gls -g or bib2gls --group.)

The resulting document doesn't show the locations as I've used save-locations=false. If you want locations, omit that option. If you only want to select entries that have been used in the document, omit selection=all.

image of document

The default behaviour is to sort by the document locale. In this example, the locale hasn't been set so bib2gls falls back on the system locale (which for me is en-GB). You can specify a different language/locale, for example, sort=de-CH-1996 or sort=pt-BR or sort=en. Order of definition is obtained with sort=none. There are other sort methods available.