# Range feature in indexing packages?

The Chicago Manual of Style says that index locators are usually pages but can also be paragraph or section numbers. It seems a good idea to use a package's range feature (if available) e.g. "For example if you have a paragraph describing the mating habits of professors, have \index{professors!mating habits|(} at the beginning and \index{professors!mating habits|)} at the end of the paragraph" (Emma Pease).

It seems like the indxcite package has something like this available \indexcite[(]{latexcomp}.

"If a citation is refered to over several paragraphs you may want to index the whole range of text. In this case you need to use three commands: one to generate the citation\cite{latexcomp}; one to mark the begining of the text to be indexed and one to mark the end of the text to be indexed."

What other indexing packages have this functionality? All of them - is it more to do with makeindex/xindy???

• The ( and ) open and close range markers are part of makeindex's syntax, which is also recognised by xindy when it's in makeindex mode (texindy). xindy's native format marks up start and end ranges differently. It's a bit of an open ended question as it comes down to a combination of the indexing application and the package used to interface with it. Apr 21, 2018 at 9:24
• It seems to work OK with xindy and imakeidx. Maybe the question would be better framed as "Are there any known combinations that are incompatible"? Apr 21, 2018 at 9:26
• I think that imakeidx's xindy option actually means use texindy, so that it uses the same syntax. Apr 21, 2018 at 9:28
• Yes, the manual says that texindy is the default. Apr 21, 2018 at 9:40

TL;DR As long as the package interface provides a way of setting the encap, then explicit range formations should be possible if the indexing is performed by an indexing application that recognises ( and ) as start and end range markers or if the package can correctly interpret and convert range markup to the appropriate syntax.

Most indexing packages use \index, which is actually a kernel command:

\documentclass{report}

\makeindex

\begin{document}
\chapter{Sample}
Foo\index{foo|(}.

\chapter{Another}
Foo\index{foo|)}.

\end{document}


(The kernel doesn't provide \printindex.) All \index does is write the argument to the .idx file (opened with \makeindex) with the corresponding page number:

\indexentry{foo|(}{1}
\indexentry{foo|)}{2}


This is makeindex syntax, which can also be processed with texindy. Indexing packages typically only modify \index if multiple indexes are supported. For example, imakeidx redefines \index to have an optional argument, which indicates the associated file, but the mandatory argument is still in makeindex syntax.

The default page-ranges module used by texindy requires a minimum range separation of three. In the following, it doesn't form a range because the range spans only two pages:

\documentclass{report}

\usepackage[xindy]{imakeidx}
\makeindex

\begin{document}
\chapter{Sample}
Foo\index{foo|(}.

\chapter{Another}
Foo\index{foo|)}.

\printindex
\end{document}


Switching to the book class makes the range span three pages:

\documentclass{book}

\usepackage[xindy]{imakeidx}
\makeindex

\begin{document}
\chapter{Sample}
Foo\index{foo|(}.

\chapter{Another}
Foo\index{foo|)}.

\printindex
\end{document}


The \glossary command has a similar function:

\documentclass{report}

\makeglossary

\begin{document}
\chapter{Sample}
Foo\glossary{foo|(}.

\chapter{Another}
Foo\glossary{foo|)}.

\end{document}


The .glo file contains:

\glossaryentry{foo|(}{1}
\glossaryentry{foo|)}{2}


So it's still using makeindex syntax.

The nomencl package provides \nomenclature, which also writes indexing information, but in this case it's more restricted as it enforces a particular syntax. For example:

\documentclass{report}

\usepackage{nomencl}

\makenomenclature

\begin{document}
Foo\nomenclature{$\pi$}{pi}.

\end{document}


The .nlo file contains:

\nomenclatureentry{a$\pi$@[{$\pi$}]\begingroup pi\nomeqref {0}|nompageref}{1}


There's no way of overriding the nompageref encap, which means there's no way of adding range markup.

The glossaries package also doesn't use or redefine the kernel commands. (The precursor glossary package used \glossary and I think early versions of glossaries used a modified version, but it doesn't any more.) In this case the encap is specified with the format key, so it's possible to form ranges:

\documentclass{report}

\usepackage{glossaries}

\makeglossaries

\newglossaryentry{foo}{name={foo},description={sample}}

\begin{document}
\chapter{Sample}
\Gls[format=(]{foo}.

\chapter{Another}
\Gls[format=)]{foo}.

\end{document}


The .glo file now looks like:

\glossaryentry{foo?\glossentry{foo}|(setentrycounter[]{page}\glsnumberformat}{1}
\glossaryentry{foo?\glossentry{foo}|)setentrycounter[]{page}\glsnumberformat}{2}


With the xindy package option it switches to xindy's native syntax:

\documentclass{report}

\usepackage[xindy]{glossaries}

\makeglossaries

\newglossaryentry{foo}{name={foo},description={sample}}

\begin{document}
\chapter{Sample}
\Gls[format=(]{foo}.

\chapter{Another}
\Gls[format=)]{foo}.

\end{document}


The .glo file now looks like:

(indexentry :tkey (("foo" "\\glossentry{foo}") ) :locref "{}{1}" :attr "pageglsnumberformat" :open-range)
(indexentry :tkey (("foo" "\\glossentry{foo}") ) :locref "{}{2}" :attr "pageglsnumberformat" :close-range)


The "noidx" version doesn't support range formations. It uses TeX to sort and collate rather than a dedicated indexing application. If ranges are used, the result is a bit weird.

\documentclass{report}

\usepackage{glossaries}

\makenoidxglossaries

\newglossaryentry{foo}{name={foo},description={sample}}

\begin{document}
\chapter{Sample}
\Gls[format=(]{foo}.

\chapter{Another}
\Gls[format=)]{foo}.

\printnoidxglossaries
\end{document}


The glossaries-extra extension package provides another indexing method:

\documentclass{report}

\usepackage[record]{glossaries-extra}

src={example-glossaries-brief}% use test data in example-glossaries-brief.bib
]

\begin{document}
\chapter{Sample}
\Gls[format=(]{lorem}.

\chapter{Another}
\Gls[format=)]{lorem}.

\printunsrtglossaries
\end{document}


This doesn't create any additional files. The indexing information is in the .aux file:

\glsxtr@record{lorem}{}{page}{(}{1}
...
\glsxtr@record{lorem}{}{page}{)}{2}


The indexing is performed by bib2gls which recognises ( and ) as open and close range markers.

It should be possible to combine ( or ) with a formatting command. For example, returning to \index and makeindex:

\documentclass{report}

\usepackage{imakeidx}
\makeindex

\begin{document}
\chapter{Sample}
Foo\index{foo|(textbf}.

\chapter{Another}
Foo\index{foo|)textbf}.

\printindex
\end{document}


This puts the entire range in bold (start page, en dash and end range).

makeindex tolerates a missing format at the end of the range:

\documentclass{report}

\usepackage{imakeidx}
\makeindex

\begin{document}
\chapter{Sample}
Foo\index{foo|(textbf}.

\chapter{Another}
Foo\index{foo|)}.

\printindex
\end{document}


This produces the same result as before.

makeindex doesn't like a conflicting format:

\documentclass{report}

\usepackage{imakeidx}
\makeindex

\begin{document}
\chapter{Sample}
Foo\index{foo|(textbf}.

\chapter{Another}
Foo\index{foo|)emph}.

\printindex
\end{document}


This triggers a warning

## Warning (input = test.idx, line = 2; output = test.ind, line = 3):
-- Range closing operator has an inconsistent encapsulator emph.


and discards the conflict, acting as though the end range was )textbf and so produces the same result as above.

With xindy, the range separator isn't included in the formatting command, so only the start and end page appear in bold, not the en dash:

\documentclass{book}

\usepackage[xindy]{imakeidx}
\makeindex

\begin{document}
\chapter{Sample}
Foo\index{foo|(textbf}.

\chapter{Another}
Foo\index{foo|)textbf}.

\printindex
\end{document}


xindy also doesn't like mis-matched formats:

\documentclass{book}

\usepackage[xindy]{imakeidx}
\makeindex

\begin{document}
\chapter{Sample}
Foo\index{foo|(textbf}.

\chapter{Another}
Foo\index{foo|)}.

\printindex
\end{document}


This gives the warning:

WARNING: Found no :close-range matching an already opened one!
Location-reference is 1 in keyword (foo).
Maybe I lost some of the regular location-references.

WARNING: Found a :close-range in the index that wasn't opened
before!
Location-reference is 3 in keyword (foo)
I'll continue and ignore this.


In this case the range is lost:

bib2gls also puts the start and end pages in bold (but not the separator):

\documentclass{report}

\usepackage[record]{glossaries-extra}

src={example-glossaries-brief}% use test data in example-glossaries-brief.bib
]

\begin{document}
\chapter{Sample}
\Gls[format={(textbf}]{lorem}.

\chapter{Another}
\Gls[format={)textbf}]{lorem}.

\printunsrtglossaries
\end{document}


bib2gls allows mismatched formats in ranges:

\documentclass{report}

\usepackage[record]{glossaries-extra}

src={example-glossaries-brief}% use test data in example-glossaries-brief.bib
]

\begin{document}
\chapter{Sample}
\Gls[format={(textbf}]{lorem}.

\chapter{Another}
\Gls[format={)}]{lorem}.

\printunsrtglossaries
\end{document}


There's no warning in this case. The start page is in bold and the end page is in the normal surrounding font. Similarly, in the following the start page is bold and the end page is emphasized:

\documentclass{report}

\usepackage[record]{glossaries-extra}

src={example-glossaries-brief}% use test data in example-glossaries-brief.bib
]

\begin{document}
\chapter{Sample}
\Gls[format={(textbf}]{lorem}.

\chapter{Another}
\Gls[format={)emph}]{lorem}.

\printunsrtglossaries
\end{document}


• Wow! Can I plagarize that for my doctoral thesis? Apr 21, 2018 at 12:06
• @DLyons If you want some further tests, the testidx package is designed to cause encap conflicts to test indexing applications. You can even get the dummy blocks to appear in reverse order with \testidx[\tstidxmaxblocks-1] to test how the application deals with close before open encaps. Apr 21, 2018 at 12:42
• @Nicola-TalbotThe "nomenclature" is particularly interesting - I didn't know it existed! I have terms that clearly belong there and, so far, I've handled them using a mixture of acronyms and a textual Notation section. It should probably have occurred to me - many a Maths/Stats book has pages devoted their specialized nomenclature. Apr 21, 2018 at 13:00
• @DLyons this document was created using glossaries-extra and bib2gls. It includes a mixture of various types of terms. Apr 21, 2018 at 13:12