[Tex/LaTex] Sort index entries

indexingsorting

This question is similar to others, but I could not find an answer that actually works for me.

This is my document:

\documentclass[12pt,a4paper]{book}
\usepackage[utf8x]{inputenx} 
\usepackage{palatino}
\usepackage{slantsc}
\linespread{1.2}       
\usepackage[LGR,T1]{fontenc}
\usepackage[english,german,polutonikogreek,italian]{babel}
\usepackage{xcolor, colortbl}
\usepackage{multicol}
\usepackage{pdfpages} 
\usepackage{hhline}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{eso-pic}
\usepackage{epstopdf}
\usepackage{longtable}
\usepackage{booktabs} 
\usepackage{tabularx} 
\usepackage{array}
\usepackage{siunitx}
\usepackage{rotating}
\usepackage{chngpage} 
\usepackage{calc} 
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage{subfig}
\usepackage{caption}
\usepackage{epigraph}
\usepackage{slashed}
\usepackage{textcomp}
\usepackage{fancybox}
\usepackage{pdflscape}
\usepackage{color}
\usepackage{verse}
\usepackage{teubner}
\usepackage{parallel}
\newcommand\textsubscript[1]{\ensuremath{{}_{\text{#1}}}}
\newcommand\textstyleFootnoteanchor[1]{\textsuperscript{#1}}
\newcommand\textstyletxt[1]{#1}
\newcommand\textstyleDefaultParagraphFont[1]{#1}
\makeatletter
\newcommand\arraybslash{\let\\\@arraycr}
\makeatother
\setlength{\skip\footins}{0.718cm} 
\renewcommand\footnoterule{
\vspace*{-0.018cm}
\setlength
\leftskip{0pt}
\setlength
\rightskip{0pt plus 1fil}
\noindent
\textcolor{black}
{\rule{0.25\columnwidth}{0.018cm}}
\vspace*{0.3cm}}
\renewcommand{\topfraction}{0.99}
\renewcommand{\bottomfraction}{0.99}
\renewcommand{\textfraction}{0.0}
\renewcommand{\floatpagefraction}{0.99}
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhead{} % clear all fields
\fancyhead[RO,LE]{\footnotesize Studi sulla tradizione indiretta di Erodoto}
\fancyfoot{} % clear all fields
\fancyfoot[LE,RO]{\thepage}
\DeclareGraphicsExtensions{.pdf,.jpg,.jpeg,.pdf,.png}            
\DeclareGraphicsRule{*}{mps}{*}{} 
\setcounter{topnumber}{9}
\setcounter{bottomnumber}{9}
\setcounter{totalnumber}{9}
\setlength{\headheight}{50pt}
\setlength{\topmargin}{5pt}

\usepackage[splitindex]{imakeidx}
\makeindex[name=n, title=Nomi di persone e luoghi] 
\makeindex[name=p, title=Passi citati nel testo]
\makeindex[name=t, title=Altri testi citati]
\makeindex[name=pap, title=Papiri e manoscritti citati nel testo]

I have 600 pages+ of text with index entries marked as follow:

\index[p]{Erodoto!8!32-3}
\index[p]{Erodoto!1!65}
%etc.

This is because I want the index to sort by book and then by chapter. The result in the index at chapter level however is sorted in the following way:

  • 1-4, 279 (this is a range)
  • 1.9, 74 (after the dot are lines in the chapter of the text quoted)
  • 10-11, 357, 359
  • 105-6, 80, 304
  • 105.3-106.1, 75
  • 105.4-108.2, 75
  • 107-114, 305
  • 2, 24
  • 24, 56
  • 207, 67
  • 3, 78

Please, could you suggest me what I need to do so that things are ordered like:

  • 1-4, 279
  • 1.11.1-4, 74
  • 1.9, 74
  • 2, 24
  • 3, 78
  • 10-11, 357, 359
  • 24, 56

Best Answer

You can use xindy instead of makeindex. It applies merging rules and it is already ready for cases like yours. We can even customize it by preparing new location classes and setting their order if we run into an unusual situation. This is a snippet from the samplexdy-mc.xdy file (it is a part of the glossaries package) where this approach was used in a large-scale.

(define-location-class "Roman-page-numbers-roman-page-numbers"
   ( :sep "{" "roman-numbers-uppercase" :sep "}{" "roman-numbers-lowercase" :sep "}" )
   :min-range-length 2
)

(define-location-class-order (
   "roman-page-numbers"
   "arabic-page-numbers"
   "arabic-section-numbers"
   "alpha-page-numbers"
   "Roman-page-numbers"
   "Alpha-page-numbers"
   "Appendix-page-numbers"
   "see" ))

I can show you the difference between the result from makeindex (the first column) and the result from xindy (the second column). We only need to eliminate the group letters, that's default option in xindy. It can be done by redefining markup for the letter group.

I enclose an example, how to process the file and a preview of pages 2 and 3.

%! *latex mal-sorting.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
\usepackage[colorlinks]{hyperref}
%\usepackage[noautomatic]{imakeidx} % splitindex
%\makeindex[title=Cities]
%\makeindex[name=p, title=Passi citati nel testo]
%\makeindex[name=n, title=Nomi di persone e luoghi] 
%\makeindex[name=t, title=Altri testi citati]
%\makeindex[name=pap, title=Papiri e manoscritti citati nel testo]
\usepackage{makeidx}
\makeindex
\usepackage{filecontents}

\begin{document}
% \printindex % The index is displaying over here with imakeidx (?)...
%http://tex.stackexchange.com/questions/142078/sort-index-entries
\begin{filecontents*}{mal-style.xdy}
;; mal-style.xdy
(markup-letter-group :open-head "~n\mycleaner{" :close-head "}")
\end{filecontents*}

First part.
\index{Prague}%
\index{Roma}%
\index{Erodoto!8!32-3}%
\index{Erodoto!1!65}%

\index{Erodoto!2!1-4}
\index{Erodoto!2!1.9}
\index{Erodoto!2!10-11}
\index{Erodoto!2!10-1}
\index{Erodoto!2!1-11}
\index{Erodoto!2!1-1}
\index{Erodoto!2!1-10}

\index{Erodoto!2!105-6}
\index{Erodoto!2!105.3-106.1}
\index{Erodoto!2!105.4-108.2}
\index{Erodoto!2!107-114}
\index{Erodoto!2!2}
\index{Erodoto!2!24}
\index{Erodoto!2!207}

\index{Erodoto!3!1-4}
\index{Erodoto!3!1.4}
\index{Erodoto!3!1.11.1-4}
\index{Erodoto!3!1.11.1-3}
\index{Erodoto!3!1.11.10-4}
\index{Erodoto!3!1.11.10-3}
\index{Erodoto!3!1.11.1-40}
\index{Erodoto!3!1.11.1-30}
\index{Erodoto!3!1.9}
\index{Erodoto!3!2}
\index{Erodoto!3!20}
\index{Erodoto!3!200}
\index{Erodoto!3!3}
\index{Erodoto!3!10-11}
\index{Erodoto!3!24}
Last part.

\begingroup % Limit changes of \thispagestyle and \mycleaner to this group only.
\def\thispagestyle#1{}% Delete the page numbers for a while...
\def\mycleaner#1{}% Delete the word groups in index from xindy...
\printindex % This file (mal-sorting.ind) was created by makeindex...
%\printindex[n] % This is supported by the imakeidx package...
\IfFileExists{mal-sorting-xindy.ind}{\input{mal-sorting-xindy.ind}}{} 
% This file was created by xindy...
\endgroup % End of the group.
\end{document}

I processed that file by these four commands:

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

mwe, makeindex and xindy comparison