I patched the bibleref
module locally:
--- a/bibleref/bibleref.sty
+++ b/bibleref/bibleref.sty
@@ -800,7 +800,7 @@ defined}{}}}
\PackageError{bibleref}{Unknown book '#1'}{}%
}%
{%
- \@bv@idxsort{\csname br@#1\endcsname}%
+ \@bv@idxsort{#1}%
\def\@bv@chidxsort{}%
\BRbooktitlestyle{\csname br@#1\endcsname}%
\let\@bv@org@bookof\BRbookof
This way, it's the abbreviated form that is used for keys, which then allows me to use \biblerefmap
as:
\biblerefmap{Gn}{1@Ancien Testament!01}
\biblerefmap{Ex}{1@Ancien Testament!02}
\biblerefmap{Lv}{1@Ancien Testament!03}
etc.
which solves my problem.
Here is a possible solution. I show it with sections, it should be easy to adapt to your setting.
(1) I define a counter and step it each time a new section is started with the \Section
command, which defines a unique command holding the section's title and whose name depends on the value of the counter.
(2) I get copies of the relevant indexing commands and patch them: \Index
requires \@Index
which in turn requires \@Wrindex
; \@Wrindex
is the heart of the process, because it writes the entry in the .idx
file. So I patch it in such a way that it immediately writes the current value of the counter. Here \protected@iwrite
is the same as \protected@write
, but does an \immediate\write
instead of the usual delayed \write
, since we don't need the page number which is known only during the output routine.
(3) The real \Index
command is a wrapper around a useful function of makeindex, usually employed for "See…".
(4) We pass makeindex the -s raphink
option, where raphink.ist
is a style file containing only
delim_0 ""
that will not add a comma after an entry.
Now a command such as \Index{Veni Sancte Spiritus}
in the "January 1st" section will write
\indexentry{Veni Sancte Spiritus|transform}{1}
in the .idx
file (assuming that 1 is the current value of the counter). If we write also \Index{Veni Sancte Spiritus}
on Pentecost, we'll have an entry such as
\indexentry{Veni Sancte Spiritus|transform}{150}
Processing with makeindex -s raphink
(done automatically by imakeidx) will give the following in the .ind
file:
\item Veni Sancte Spiritus \transform{1, 150}
The macro \transform
reads the comma separated list and splits it using then the commands \csname cursec1\endcsname
and \csname cursec150\endcsname
that contain the correct section titles.
The implementation
Here are the macros in a sample document.
\begin{filecontents*}{raphink.ist}
delim_0 ""
\end{filecontents*}
\documentclass[a4paper]{report}
\usepackage{etoolbox}
\newcounter{indexcnt}
\newcommand\Section[1]{%
\stepcounter{indexcnt}%
\expandafter\gdef\csname cursec\theindexcnt\endcsname{#1}%
\section{#1}}
\usepackage{imakeidx}
\makeindex[options=-s raphink]
\makeatletter
\let\@Index\@index
\patchcmd{\@Index}{\@wrindex}{\@Wrindex}{}{}
\let\@Wrindex\@wrindex
\patchcmd{\@Wrindex}{\thepage}{\theindexcnt}{}{}
\let\xIndex\index
\patchcmd{\xIndex}{\@index}{\@Index}{}{}
\patchcmd{\xIndex}{\@index}{\@Index}{}{}
\let\protected@iwrite\protected@write
\patchcmd{\protected@iwrite}{\write}{\immediate\write}{}{}
\patchcmd{\@Wrindex}{\protected@write}{\protected@iwrite}{}{}
\makeatother
\newcommand{\Index}[1]{\xIndex{#1|transform}}
\newcommand{\transform}[1]{\forcsvlist\decodesec{#1}}
\newcommand{\decodesec}[1]{, \csname cursec#1\endcsname}
\begin{document}
\chapter{Christmas}
\Section{January 1st}
...
Veni Sancte Spiritus\Index{Veni Sancte Spiritus}
...
\chapter{Easter}
\Section{Pentecost}
...
Veni Sancte Spiritus\Index{Veni Sancte Spiritus}
...
\printindex
\end{document}
Best Answer
If you expand the macro before
\index
reads it the sorting should be correct after the content. You can do this using\expandafter
:It is shorter if you put the
{ }
inside the definition:For more complex content, i.e. with multiple macros you should expand the content fully using
\edef
(or maybe\protected@edef
):If you want to keep the
\temp
definition local use:instead.