9

I'm working on a document that makes a lot of references to the bible, and I have two indexes set up, one of topics and the other by verse. Currently, in the index by verse, Luke 10:25 is indexed before Luke 1:5, for example, because that's the alphabetical order. Is there any easy way to get the entries to appear in the order a human would expect based on the three fields (alphabetically by book, numerically by chapter, verse)?

I came across the package bibleref, but it seems to not handle this. According to the docs, what it seems to be designed to do is allow you to index the books of the bible according to their biblical order rather than alphabetically, but that's not what I care about.

  • 2
    Can you please provide an example of (not) working code to play with? – egreg Jan 29 '21 at 17:29
  • 7
    it would be easier if you provided a test example but the usual way would be to index it as Luke:01:05 so sorting works out and apply a formatting command that drops leading zeros, eg if it is formatted as Luke\number01:\number:05 it will sort and typeset as you wish. – David Carlisle Jan 29 '21 at 17:35
  • 1
    I know this question has been answered. There is another package that you might consider—since it looks like you are doing scripture references. The bibleref package is quite nice and already handles indexing issues like you are seeking. – jlconlin Feb 02 '21 at 22:16

3 Answers3

12

enter image description here

\documentclass{article}

\usepackage{imakeidx}

\makeindex

\newcommand\bindex[3]{\index{#1:\string\number\string\numexpr\the\numexpr1000+#2\relax-1000:\string\number\string\numexpr\the\numexpr1000+#3\relax-1000}} \begin{document}

zzz\bindex{Luke}{10}{25} zzz\bindex{Luke}{1}{5} zzz\bindex{Matthew}{1}{1}

\printindex \end{document}

If you look in the generated .ind file you see what it is doing:

\begin{theindex}

\item Luke:\number\numexpr1001-1000:\number\numexpr1005-1000, 1 \item Luke:\number\numexpr1010-1000:\number\numexpr1025-1000, 1

\indexspace

\item Matthew:\number\numexpr1001-1000:\number\numexpr1001-1000, 1

\end{theindex}

1000 gets added so all numbers end up the same length, then (after sorting) 1000 is subtracted and \number applied to remove leading zeros.

David Carlisle
  • 757,742
6

Pad the numbers with zeros and use the @ feature for sorting.

\documentclass{article}
\usepackage{imakeidx}

\makeindex

\ExplSyntaxOn \NewDocumentCommand{\indexverse}{mmm} {% #1 = name, #2 = chapter, #3 = verse \index {% the sorting part #1\prg_replicate:nn{4-\tl_count:n{#2}}{0}#2\prg_replicate:nn{4-\tl_count:n{#3}}{0}#3 @ #1~#2:#3 } } \ExplSyntaxOff

\begin{document}

text \indexverse{Luke}{10}{25} \indexverse{Luke}{10}{5}

\printindex

\end{document}

This is the .idx file

\indexentry{Luke00100025@Luke 10:25}{1}
\indexentry{Luke00100005@Luke 10:5}{1}

and the .ind file

\begin{theindex}

\item Luke 10:5, 1 \item Luke 10:25, 1

\end{theindex}

egreg
  • 1,121,712
3

Thanks, egreg and David Carlisle, for your help! Having seen what technique you used, I decided to reimplement the same technique outside of latex, like this:

perl -i -pe 's/(\d+)/$$1+1000/ge' jesus.idx
makeindex jesus.idx -o jesus.ind 
perl -i -pe 's/(\d\d\d\d)/$$1-1000/ge' jesus.ind

A disadvantage is that this method won't work for people running Windows. Advantages are that it only adds two lines of code to my build script, it's pretty readable, and it correctly handles strings that are not quite in the same format, e.g., Luke 5 or Matthew 8:27-9:1. So I thought I would post this as a self-answer, and that way others coming across this can have one more method to choose from.