# Index sorting where numbers are indexed

I have a vast document where I have a separate index of dates (really only the year or year range of particular events). I'm using memoir.

Sometimes the year is known exactly

\index[dates]{1875!Event xyz}


Sometimes the year is a range

\index[dates]{1822--1867!Event abc}


These sort in index as

1822-1897
Event xxxx 77,87
Event pppp 73

1829-1844
Event zzz 79

1756
Event xxx2 99

In other words, date ranges sort alphabetically and are separated from the single numeric entries which sort numerically yielding an odd ordering. Is there any way I get numbers to sort alphabetically and not numerically so that I can get ordering

1
1--5
2
3
3--5
4

rather than

1--5
3--5
1
2
3
4

The index entries are via a macro

\newcommand{\indexdate}[2]{#1\index[dates]{#1!{#2}}}


And so a single change to the macro might achieve what I want without having to manually edit every one of a couple of thousands of entries to impose a sort order.

I have hit a roadblock on this one. I don't think a MWE would be of additional use here, but happy to post one.

• An MWE is always of use, especially if you want people to test their answers before posting. Apr 13, 2013 at 18:19
• you might consider adding a sort field with a space at the end, so that you would get \index[dates]{1875 @1875!Event xyz}, so that a single year would always sort before a year span. (i'm not sure i understand how 1756 sorts after 1829 in any case.) Apr 13, 2013 at 18:20
• Barbara's space idea works brilliantly (or via my macro which is now \newcommand{\indexdate}[2]{#1\index[dates]{#1 @#1!{#2}}}. (I take the comment about MWEs). Barbara, yes 1756 does indeed sort AFTER 1829--1844, but the space idea solves it. Apr 13, 2013 at 19:03

Makeindex sorts numbers in numerical order:

1
9
10


However ranges are not numbers. The range symbol -- prevents Makeindex to take such an entry as number. These entries are sorted in lexical order. Also they precede the numbers.

You can specify a sort key for Makeindex. If the sort key is a number, then the number of digits should be the same for years and year ranges, e.g.:

\newcommand{\indexdate}[2]{#1\index[dates]{#10000@#1!#2}}
\newcommand{\indexdaterange}[3]{#1--#2\index[dates]{#1#2@#1--#2!#3}}


The sortkey is the entry before @. The sort key of a year range is just the two four-digit years. In case of a year, the sort key is the four-digit year, followed by four zeros to fill the eight digits for all numerical sort keys.

Alternatively the sort key can add a non-digit, then the entries are sorted in lexical order, with four-digit years, the numerical order is not really needed:

\newcommand{\indexdate}[2]{#1\index[dates]{#1x@#1!#2}}

• heiko-oberdiek solution also works well and provides a useful template for the future. For my particular problem simply adding a space as suggested by @barbara-beeton is what I'm going for. The same macro: \newcommand{\indexdate}[2]{#1\index[dates]{#1 @#1!{#2}}} serves for both single numbers and ranges, similar to heiko-oberdiek second solution. Many thanks to both. I'm not sure how to mark answers as solutions. Apr 13, 2013 at 19:24

Xindy is already ready for such cases thanks to merging and sorting rules. I enclose an example and a preview of the last page. Please run it with shell escape on, or, run these three lines on this example (pdflatex and xelatex can be used right away too as font related packages are not activated yet):

lualatex mal-xindy-numbers.tex
xindy -M texindy -L general -C utf8 -M mal-style -o dates.ind dates.idx
lualatex mal-xindy-numbers.tex

%! *latex mal-xindy-numbers.tex
%  with shell escape on
\documentclass{memoir}
%\usepackage{xltxtra} % use: inputenc (pdflatex), fontspec (xelatex)
\usepackage[xindy]{imakeidx}
\indexsetup{firstpagestyle=empty}
\makeatletter\def\imki@progdefault{xindy}\makeatother
\makeindex[name=dates, title=Milestone events, options=-M texindy -L general -C utf8 -M mal-style]
\def\indexdate#1#2{#1\index[dates]{#1!#2}}
\usepackage{filecontents}
\begin{filecontents*}{mal-style.xdy}
(markup-locref :attr "default" :open "\hyperpage{" :close "}")
\end{filecontents*}

\begin{document}
\indexdate{1}{Event A}
\indexdate{1}{Event I}
\indexdate{1--5}{Event I}
\indexdate{1--5}{Event X}
\indexdate{1--5}{Event B}
\indexdate{2}{Event C}
\indexdate{3}{Event D}
\indexdate{3--5}{Event E}
\indexdate{4}{Event F}
\indexdate{1950}{Event G}
\indexdate{1950}{Event K}
\newpage
\indexdate{1950}{Event G}
\indexdate{1950}{Event K}
\indexdate{1950--1955}{Event G}
\indexdate{1948}{Event L}
\indexdate{1949--1951}{Event G}
\indexdate{1949--1950}{Event H}
\printindex[dates]
\end{document}