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}
Following the example you give, using the memoir
class, here is a simple way to implement what you want. Memoir
may be a good option if you have precise, complex needs, because it is very comprehensive, especially for long documents.
Because memoir
's \frontmatter
, \mainmatter
and friends alter the way section numbering is done, I suggest you create a whole new counter, since you are not really using it as a sectioning command anyway. If you need to add the paragraphs to the table of contents, it is possible too, so no worries there (just ask).
Here is the example document:
\documentclass{memoir}
% Load dummy text
\usepackage{lipsum}
% We create a counter
\newcounter{paracount}
% We create the paragraph command
\def\para{%
\refstepcounter{paracount}%
\noindent\textbf{\theparacount.\quad}}
% We create an index
\makeindex
% We tell memoir to index paragraphs and not pages
\renewcommand{\index}[1]{\specialindex{\jobname}{paracount}{#1}}
\begin{document}
\frontmatter
\para \index{Front matter entry} \lipsum[4]
\mainmatter
\para \index{First entry} \lipsum[1]
\para \index{Second entry} \lipsum[2]
\para \index{Third entry} \lipsum[3]
\printindex
\end{document}
Note that you can tell memoir to index things based on any counter, you just need to specify it in the \specialindex{\jobname}{<counter>}{#1}
line.
Now, all you need to do is run LaTeX, then MakeIndex, then LaTeX again.
Best Answer
In order to use section numbers instead of page numbers it is necessary to redefine the way, the index entry is written to
\jobname.idx
. That is basically easy, if the packageimakeidx
is used.In its manual,
imakeidx
the author writes, that\imki@wrindexentry
should be redefined to apply for other styles. Looking into the package, there is a similar command used with\thepage
as argument, so redefined it, using\thesection
.However,
makeindex
as external processor complains about the new format if\thesection
writes its numbers as1.1
etc., i.e. with dots. Usingxindy
solves this problem, by applying a new alphabet or location-class, this is done insectionindex_xindy.xdy
, as well as removing the,
separator and inserting-----
instead.Content of
sectionindex_xindy.xdy
In order to make this work for figures/tables, I just redefined the command again within wrappers for
figure
andtable
environment. You have redefine\thefigure
and\thetable
explicitly, since it seems, that they introduce a trailing\relax
command just before the figure/table number.Please note, that this does not work correctly with hyperlinks so far,regarding the figure/table index entries.
Enabling --shell-escape is mandatory.