For a given book which is a daily devotional, I have no page numbers at all, but each section corresponds to a day in the year, with one day per page. I generate an index of Bible references in the end of the book, and I link the Bible references to the page where they are quoted. But since there are no page numbers in the book, the index must contain the day (i.e. the secion, e.g. "13 Mai" instead of 151) instead of the page number.
So far, my (ugly) solution was to output the section name and page in the logs with:
\typeout{Date on page \thepage:\thesection:\chaphead}%
and then use a shell script to parse the logs and modify the generated index (.ind file) with sed:
#!/bin/bash
NAME="$1"
while read -r page day month; do
bsmonth=$(sed -e 's@\\@\\\\@g' <<<$month)
sed -i "s@textrm{\([^,]*, \)\?$page\(, [^,]*\)\?}@textrm{\1\\\\hyperlink{page.$page}{\\\\mbox{\\\\scshape\\\\makedate{$day}~$bsmonth}}\2}@g" $NAME.ind
done < <(sed -n 's@Date on page \([0-9]\+\):\([0-9]\+\):\(.*\)@\1 \2 \3@p' $NAME.log)
I would call LaTeX this way:
%.pdf: %.tex
TEXINPUTS=$(TEXINPUTS) pdflatex -shell-escape -interaction=batchmode $<
# Modify index to use dates instead of pages
./index_dates.sh $*
# No -shell-escape to prevent re-creation of index
TEXINPUTS=$(TEXINPUTS) pdflatex -interaction=batchmode $<
I'm using imakeidx
so the index is automatically regenerated when I compile the document. In TeXLive 2009, not passing -shell-escape
prevented imakeidx
from rebuilding the index, and thus from erasing the changes made by index_dates.sh
, so it worked fine (although still ugly).
Now in TeXLive 2010, the -shell-escape
trick doesn't work, and before I switch to another ugly trick, I'd like to think of rewriting this piece of code in proper TeX. Can you give me some hint as to how to do it properly?
-
Should I generate dynamic macros such as:
\def\pagemonth@\csname \thepage{\thesection~\chaphead}
and then modify the index? If so, how do I modify the index?
-
Should I write these macros to a separate file and import it later on (and how to do that)?
-
Should I hook into
imakeidx
(and how)? -
Should I replace
imakeidx
with another package that would allow this more easily? -
Should I switch to another index builder (such as
xindy
) and what parameters would I pass it? -
Should I add a "style" for page numbers in the index which would actually be a call to a macro replacing with my content?
Best Answer
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, whereraphink.ist
is a style file containing onlythat will not add a comma after an entry.
Now a command such as
\Index{Veni Sancte Spiritus}
in the "January 1st" section will writein 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 asProcessing with
makeindex -s raphink
(done automatically by imakeidx) will give the following in the.ind
file: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.